Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

98 lines
2.8 KiB

using System.Diagnostics;
using System.Text;
namespace StabilityMatrix.Core.Processes;
/// <summary>
/// Process supporting parsing of ANSI escape sequences
/// </summary>
public class AnsiProcess : Process
{
private AsyncStreamReader? stdoutReader;
private AsyncStreamReader? stderrReader;
public AnsiProcess(ProcessStartInfo startInfo)
{
StartInfo = startInfo;
EnableRaisingEvents = false;
StartInfo.UseShellExecute = false;
StartInfo.CreateNoWindow = true;
StartInfo.RedirectStandardOutput = true;
StartInfo.RedirectStandardInput = true;
StartInfo.RedirectStandardError = true;
// Need this to parse ANSI escape sequences correctly
StartInfo.StandardOutputEncoding = new UTF8Encoding(false);
StartInfo.StandardErrorEncoding = new UTF8Encoding(false);
StartInfo.StandardInputEncoding = new UTF8Encoding(false);
}
/// <summary>
/// Start asynchronous reading of stdout and stderr
/// </summary>
/// <param name="callback">Called on each new line</param>
public void BeginAnsiRead(Action<ProcessOutput> callback)
{
var stdoutStream = StandardOutput.BaseStream;
stdoutReader = new AsyncStreamReader(
stdoutStream,
s =>
{
if (s == null)
return;
callback(ProcessOutput.FromStdOutLine(s));
},
StandardOutput.CurrentEncoding
);
var stderrStream = StandardError.BaseStream;
stderrReader = new AsyncStreamReader(
stderrStream,
s =>
{
if (s == null)
return;
callback(ProcessOutput.FromStdErrLine(s));
},
StandardError.CurrentEncoding
);
stdoutReader.BeginReadLine();
stderrReader.BeginReadLine();
}
/// <summary>
/// Waits for output readers to finish
/// </summary>
public async Task WaitUntilOutputEOF(CancellationToken ct = default)
{
if (stdoutReader is not null)
{
await stdoutReader.EOF.WaitAsync(ct).ConfigureAwait(false);
}
if (stderrReader is not null)
{
await stderrReader.EOF.WaitAsync(ct).ConfigureAwait(false);
}
}
/// <summary>
/// Cancels stream readers, no effect if already cancelled
/// </summary>
public void CancelStreamReaders()
{
stdoutReader?.CancelOperation();
stderrReader?.CancelOperation();
}
protected override void Dispose(bool disposing)
{
CancelStreamReaders();
stdoutReader?.Dispose();
stdoutReader = null;
stderrReader?.Dispose();
stderrReader = null;
base.Dispose(disposing);
}
}