mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-04 09:06:23 +02:00
Add singleton/system manifest, process args, and async management support
This commit is contained in:
@@ -8,42 +8,60 @@ public static class ProcessManager
|
||||
{
|
||||
private static readonly ConcurrentDictionary<int, (Process Process, Thread Thread)> processes = new();
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, ConcurrentHashSet<int>> processesByType = new();
|
||||
|
||||
private static int nextProcessId = 0;
|
||||
|
||||
public static int SpawnProcess<T>() where T : Process, new()
|
||||
private static int nextSystemProcessId = -1;
|
||||
|
||||
public static int SpawnProcess<T>(string[]? args = null) where T : Process, new()
|
||||
{
|
||||
int id = GetNextProcessId();
|
||||
if (ProcessManifest.HasFlag<T>(ProcessManifest.ProcessManifestFlags.Singleton) && IsProcessRunning<T>())
|
||||
{
|
||||
throw new InvalidOperationException($"An instance of process type {typeof(T).Name} is already running.");
|
||||
}
|
||||
|
||||
int id = ProcessManifest.HasFlag<T>(ProcessManifest.ProcessManifestFlags.System) ? GetNextSystemProcessId() : GetNextProcessId();
|
||||
|
||||
T process = new()
|
||||
{
|
||||
Id = id
|
||||
};
|
||||
|
||||
processesByType.AddOrUpdate(typeof(T), _ => [id], (_, set) =>
|
||||
{
|
||||
set.Add(id);
|
||||
return set;
|
||||
});
|
||||
|
||||
Thread thread = new(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Process {process.Name} (ID: {process.Id}) terminated with an exception: {ex}");
|
||||
process.Run(args ?? []);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = processes.TryRemove(id, out _);
|
||||
processes.TryRemove(id, out _);
|
||||
|
||||
if (processesByType.TryGetValue(typeof(T), out var set))
|
||||
{
|
||||
set.TryRemove(id);
|
||||
if (set.Count == 0)
|
||||
processesByType.TryRemove(typeof(T), out _);
|
||||
}
|
||||
|
||||
WindowManager.CloseWindowsForProcess(id);
|
||||
}
|
||||
});
|
||||
|
||||
_ = processes.TryAdd(id, (process, thread));
|
||||
|
||||
processes.TryAdd(id, (process, thread));
|
||||
thread.Start();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public static void StopProcess(int processId)
|
||||
public static void StopProcess(int processId, bool waitForExit = false)
|
||||
{
|
||||
if (!processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
|
||||
{
|
||||
@@ -51,10 +69,17 @@ public static class ProcessManager
|
||||
}
|
||||
|
||||
entry.Process.RequestStop();
|
||||
}
|
||||
|
||||
WindowManager.CloseWindowsForProcess(processId);
|
||||
public static async Task StopProcessAndWaitAsync(int processId)
|
||||
{
|
||||
if (!processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ = processes.TryRemove(processId, out _);
|
||||
entry.Process.RequestStop();
|
||||
await Task.Run(() => entry.Thread.Join());
|
||||
}
|
||||
|
||||
public static void StopAllProcesses()
|
||||
@@ -77,6 +102,25 @@ public static class ProcessManager
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsProcessRunning<T>() where T : Process
|
||||
{
|
||||
return processesByType.TryGetValue(typeof(T), out var set) && set.Count > 0;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetProcessesOfType<T>() where T : Process
|
||||
{
|
||||
if (processesByType.TryGetValue(typeof(T), out var set))
|
||||
{
|
||||
foreach (int processId in set)
|
||||
{
|
||||
if (processes.TryGetValue(processId, out (Process Process, Thread Thread) entry) && entry.Process is T typedProcess)
|
||||
{
|
||||
yield return typedProcess;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Process> GetAllProcesses()
|
||||
{
|
||||
foreach ((Process Process, Thread Thread) entry in processes.Values)
|
||||
@@ -101,4 +145,9 @@ public static class ProcessManager
|
||||
{
|
||||
return nextProcessId++;
|
||||
}
|
||||
|
||||
private static int GetNextSystemProcessId()
|
||||
{
|
||||
return nextSystemProcessId--;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user