I have an app that opens other consoles in background:
var fileContent = File.ReadAllText(pathToJsonFile);
var obj = JsonConvert.DeserializeObject<ArrayOfCommands[]>(fileContent);
var tasks = obj.Select(o => new Task(() =>
{
var pm = new ProcessManager(null, null);
var args = "-a test -b other test";
pm.DoCore("OtherConsoleCore.dll", args, (str) => Console.WriteLine(str), (err) => Console.WriteLine(err));
})).ToList();
while(true) { } // keep main window open
and ProcessManager:
internal sealed class ProcessManager
{
private readonly ILog _log;
private readonly string _pathToExecutable;
private static Process _currentProcess;
public ProcessManager(ILog log, string pathToExecutable)
{
_log = log;
_pathToExecutable = pathToExecutable;
}
public void Do(string args, Action<string> successAction = null, Action<string> errorAction = null, string workingDir = null)
{
DoAsync(_log, _pathToExecutable, args, successAction, errorAction, workingDir);
}
public void DoCore(string pathToDll, string args, Action<string> successAction = null, Action<string> errorAction = null, string workingDir = null)
{
DoCoreAsync(_log, pathToDll, args, successAction, errorAction, workingDir);
}
private static void DoAsync(ILog log, string pathToExe, string args, Action<string> successAction = null, Action<string> errorAction = null, string workingDir = null)
{
log?.Debug($"Process exe: {pathToExe}");
log?.Debug($"Process args: {args}");
ProcessStartInfo pi = new ProcessStartInfo();
pi.UseShellExecute = false;
pi.CreateNoWindow = true;
pi.FileName = pathToExe;
pi.Arguments = args;
pi.WorkingDirectory = string.IsNullOrWhiteSpace(workingDir) ? Path.GetDirectoryName(pathToExe) : workingDir;
pi.RedirectStandardError = errorAction != null;
pi.RedirectStandardOutput = successAction != null;
using (Process p = new Process())
{
if (successAction != null)
{
p.OutputDataReceived += (s, ev) =>
{
successAction?.Invoke(ev.Data);
};
}
if (errorAction != null)
{
p.ErrorDataReceived += (s, ev) =>
{
errorAction?.Invoke(ev.Data);
};
}
p.StartInfo = pi;
p.Start();
_currentProcess = p;
if (errorAction != null)
{
p.BeginErrorReadLine();
}
if (successAction != null)
{
p.BeginOutputReadLine();
}
p.WaitForExit();
}
}
internal static void CloseCurrentProcess()
{
try
{
_currentProcess?.Kill(true);
}
catch { }
_currentProcess = null;
}
private static void DoCoreAsync(ILog log, string pathToDll, string args, Action<string> successAction = null, Action<string> errorAction = null, string workingDir = null)
{
log?.Debug($"Process dll: {pathToDll}");
log?.Debug($"Process args: {args}");
var workDir = string.IsNullOrWhiteSpace(workingDir) ? Path.GetDirectoryName(pathToDll) : workingDir;
var arguments = string.Concat(pathToDll, " ", args);
DoAsync(log, "dotnet", arguments, successAction, errorAction, workDir);
}
}
Those opened windows are still in background for listening some jobs.
Now, I have:
// in main window
Console.CancelKeyPress += Console_CancelKeyPress;
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
// how to close opened tasks/processes ?
}
When I press CTRL+C, I want to close the tasks/processes opened. How to do that ?