Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Instances v3.0.200
BepInEx/core/Instances/netstandard2.0/Instances.dll
Decompiled 5 months agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using Instances.Exceptions; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Malte Rosenbjerg")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Rosenbjerg Softworks")] [assembly: AssemblyDescription("A .NET Standard Process wrapper with an elegant API, for both asyncronous and syncronous use, providing both Events and support for Tasks with cancellation support")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3d9beb6e6a6a5ede491dcaba32389350f10b6f74")] [assembly: AssemblyProduct("Instances")] [assembly: AssemblyTitle("Instances")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/rosenbjerg/Instances")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Instances { public static class Instance { public static IProcessInstance Start(string path, string arguments = "", EventHandler<string>? outputHandler = null, EventHandler<string>? errorHandler = null) { return Start(new ProcessStartInfo { FileName = path, Arguments = arguments }, outputHandler, errorHandler); } public static IProcessInstance Start(ProcessStartInfo startInfo, EventHandler<string>? outputHandler, EventHandler<string>? errorHandler) { ProcessArguments processArguments = new ProcessArguments(startInfo); if (outputHandler != null) { processArguments.OutputDataReceived += outputHandler; } if (errorHandler != null) { processArguments.ErrorDataReceived += errorHandler; } return processArguments.Start(); } public static IProcessResult Finish(string path, string arguments = "", EventHandler<string>? outputHandler = null, EventHandler<string>? errorHandler = null) { return Finish(new ProcessStartInfo { FileName = path, Arguments = arguments }, outputHandler, errorHandler); } public static IProcessResult Finish(ProcessStartInfo startInfo, EventHandler<string>? outputHandler = null, EventHandler<string>? errorHandler = null) { using IProcessInstance processInstance = Start(startInfo, outputHandler, errorHandler); return processInstance.WaitForExit(); } public static Task<IProcessResult> FinishAsync(string path, string arguments = "", CancellationToken cancellationToken = default(CancellationToken), EventHandler<string>? outputHandler = null, EventHandler<string>? errorHandler = null) { return FinishAsync(new ProcessStartInfo { FileName = path, Arguments = arguments }, cancellationToken, outputHandler, errorHandler); } public static async Task<IProcessResult> FinishAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default(CancellationToken), EventHandler<string>? outputHandler = null, EventHandler<string>? errorHandler = null) { using IProcessInstance instance = Start(startInfo, outputHandler, errorHandler); return await instance.WaitForExitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } } public interface IProcessInstance : IDisposable { IReadOnlyCollection<string> OutputData { get; } IReadOnlyCollection<string> ErrorData { get; } event EventHandler<IProcessResult>? Exited; event EventHandler<string>? OutputDataReceived; event EventHandler<string>? ErrorDataReceived; Task SendInputAsync(string input); void SendInput(string input); Task<IProcessResult> WaitForExitAsync(CancellationToken cancellationToken = default(CancellationToken)); IProcessResult WaitForExit(); IProcessResult Kill(); } public interface IProcessResult { int ExitCode { get; } IReadOnlyList<string> OutputData { get; } IReadOnlyList<string> ErrorData { get; } } public class ProcessArguments { private readonly ProcessStartInfo _processStartInfo; public bool IgnoreEmptyLines { get; set; } public int DataBufferCapacity { get; set; } = int.MaxValue; public event EventHandler<IProcessResult>? Exited; public event EventHandler<string>? OutputDataReceived; public event EventHandler<string>? ErrorDataReceived; public ProcessArguments(string path, string arguments) : this(new ProcessStartInfo { FileName = path, Arguments = arguments }) { } public ProcessArguments(ProcessStartInfo processStartInfo) { _processStartInfo = processStartInfo; } public IProcessInstance Start() { _processStartInfo.CreateNoWindow = true; _processStartInfo.UseShellExecute = false; _processStartInfo.RedirectStandardOutput = true; _processStartInfo.RedirectStandardInput = true; _processStartInfo.RedirectStandardError = true; Process process = new Process { StartInfo = _processStartInfo, EnableRaisingEvents = true }; ProcessInstance processInstance = new ProcessInstance(process, IgnoreEmptyLines, DataBufferCapacity); processInstance.Exited += this.Exited; processInstance.OutputDataReceived += this.OutputDataReceived; processInstance.ErrorDataReceived += this.ErrorDataReceived; try { process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); return processInstance; } catch (Win32Exception ex) when (ex.Message.Contains("The system cannot find the file specified") || ex.Message.Contains("No such file or directory")) { throw new InstanceFileNotFoundException(_processStartInfo.FileName, ex); } } } public static class ProcessArgumentsExtensions { public static IProcessResult StartAndWaitForExit(this ProcessArguments processArguments) { using IProcessInstance processInstance = processArguments.Start(); return processInstance.WaitForExit(); } public static async Task<IProcessResult> StartAndWaitForExitAsync(this ProcessArguments processArguments, CancellationToken cancellationToken = default(CancellationToken)) { using IProcessInstance instance = processArguments.Start(); return await instance.WaitForExitAsync(cancellationToken); } } public class ProcessInstance : IProcessInstance, IDisposable { private readonly bool _ignoreEmptyLines; private readonly int _dataBufferCapacity; private readonly Process _process; private readonly TaskCompletionSource<bool> _mainTask = new TaskCompletionSource<bool>(); private readonly TaskCompletionSource<bool> _stdoutTask = new TaskCompletionSource<bool>(); private readonly TaskCompletionSource<bool> _stderrTask = new TaskCompletionSource<bool>(); private readonly Queue<string> _outputData = new Queue<string>(); private readonly Queue<string> _errorData = new Queue<string>(); private CancellationTokenRegistration? _cancellationTokenRegister; public IReadOnlyCollection<string> OutputData => _outputData.ToList().AsReadOnly(); public IReadOnlyCollection<string> ErrorData => _errorData.ToList().AsReadOnly(); public event EventHandler<IProcessResult>? Exited; public event EventHandler<string>? OutputDataReceived; public event EventHandler<string>? ErrorDataReceived; internal ProcessInstance(Process process, bool ignoreEmptyLines, int dataBufferCapacity) { process.OutputDataReceived += ReceiveOutput; process.ErrorDataReceived += ReceiveError; process.Exited += ReceiveExit; _process = process; _ignoreEmptyLines = ignoreEmptyLines; _dataBufferCapacity = dataBufferCapacity; } public async Task SendInputAsync(string input) { ThrowIfProcessExited(); await _process.StandardInput.WriteAsync(input).ConfigureAwait(continueOnCapturedContext: false); await _process.StandardInput.FlushAsync().ConfigureAwait(continueOnCapturedContext: false); } public void SendInput(string input) { ThrowIfProcessExited(); _process.StandardInput.Write(input); _process.StandardInput.Flush(); } public IProcessResult Kill() { try { _process.Kill(); return GetResult(); } catch (InvalidOperationException innerException) { throw new InstanceProcessAlreadyExitedException(innerException); } } public async Task<IProcessResult> WaitForExitAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (cancellationToken != default(CancellationToken)) { _cancellationTokenRegister = cancellationToken.Register(delegate { if (!_process.HasExited) { _process.Kill(); } }); } await _mainTask.Task.ConfigureAwait(continueOnCapturedContext: false); return GetResult(); } public IProcessResult WaitForExit() { try { _process.WaitForExit(); return GetResult(); } catch (SystemException innerException) { throw new InstanceProcessAlreadyExitedException(innerException); } } public void Dispose() { _process.Dispose(); _cancellationTokenRegister?.Dispose(); } private void ReceiveExit(object sender, EventArgs e) { object sender2 = sender; _cancellationTokenRegister?.Dispose(); Task.WhenAll<bool>(_stdoutTask.Task, _stderrTask.Task).ContinueWith(delegate { this.Exited?.Invoke(sender2, GetResult()); return _mainTask.TrySetResult(result: true); }); } private void ReceiveOutput(object _, DataReceivedEventArgs e) { AddData(_outputData, e.Data, this.OutputDataReceived, _stdoutTask); } private void ReceiveError(object _, DataReceivedEventArgs e) { AddData(_errorData, e.Data, this.ErrorDataReceived, _stderrTask); } private void AddData(Queue<string> dataList, string? data, EventHandler<string>? eventHandler, TaskCompletionSource<bool> taskCompletionSource) { if (data == null) { taskCompletionSource.TrySetResult(result: true); } else if (!_ignoreEmptyLines || !(data == string.Empty)) { dataList.Enqueue(data); for (int i = 0; i < dataList.Count - _dataBufferCapacity; i++) { dataList.Dequeue(); } eventHandler?.Invoke(this, data); } } private IProcessResult GetResult() { return new ProcessResult(_process.HasExited ? _process.ExitCode : (-100), _outputData.ToArray(), _errorData.ToArray()); } private void ThrowIfProcessExited() { if (_process.HasExited) { throw new InstanceProcessAlreadyExitedException(); } } } public class ProcessResult : IProcessResult { public int ExitCode { get; } public IReadOnlyList<string> OutputData { get; } public IReadOnlyList<string> ErrorData { get; } internal ProcessResult(int exitCode, IReadOnlyList<string> outputData, IReadOnlyList<string> errorData) { OutputData = outputData; ErrorData = errorData; ExitCode = exitCode; } } } namespace Instances.Exceptions { public class InstanceException : Exception { public InstanceException(string msg, Exception innerException) : base(msg, innerException) { } } public class InstanceFileNotFoundException : InstanceException { public InstanceFileNotFoundException(string fileName, Exception innerException) : base("File not found: " + fileName, innerException) { } } public class InstanceProcessAlreadyExitedException : Exception { public InstanceProcessAlreadyExitedException() : base("The process instance has already exited") { } public InstanceProcessAlreadyExitedException(Exception innerException) : base("The process instance has already exited", innerException) { } } }