1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
using System;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Threading;
namespace manager;
public partial class ProcessWindow : Window
{
private readonly Process _process = new();
private readonly StringBuilder _output = new();
public ProcessWindow()
{
InitializeComponent();
}
public ProcessWindow(string fileName, string? arguments = null, string? workingDir = null)
: this()
{
Title = $"{fileName} - Process Output";
CloseButton.Click += (_, _) => Close();
_process.StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments ?? "",
WorkingDirectory = workingDir ?? "",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8,
};
_process.EnableRaisingEvents = true;
_process.Exited += (_, _) =>
{
_process.WaitForExit();
Dispatcher.UIThread.Post(() =>
{
StatusText.Text = $"Exited (Code: {_process.ExitCode})";
AppendOutput($"[Process exited, code: {_process.ExitCode}]");
});
};
StartProcess();
}
private async void StartProcess()
{
try
{
StatusText.Text = "Starting...";
_process.Start();
StatusText.Text = $"Running (PID: {_process.Id})";
var stdoutTask = ReadStreamAsync(_process.StandardOutput);
var stderrTask = ReadStreamAsync(_process.StandardError);
await Task.WhenAll(stdoutTask, stderrTask);
}
catch (Exception ex)
{
Dispatcher.UIThread.Post(() =>
{
AppendOutput($"[Start failed] {ex.Message}");
StatusText.Text = "Start failed";
});
}
}
private async Task ReadStreamAsync(System.IO.StreamReader reader)
{
var buffer = new char[4096];
int charsRead;
while ((charsRead = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
var segment = new string(buffer, 0, charsRead);
Dispatcher.UIThread.Post(() => AppendOutput(segment));
}
}
private void AppendOutput(string text)
{
_output.Append(text);
OutputText.Text = _output.ToString();
OutputScroll.ScrollToEnd();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (!_process.HasExited)
{
try { _process.Kill(); } catch { }
}
_process.Dispose();
}
}
|