0

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 ?

Snake Eyes
  • 16,287
  • 34
  • 113
  • 221
  • Do you need graceful cancellation or killing child processes will be enough? – Dennis Jan 12 '21 at 09:04
  • When close main window, want to close its children...Of course, in every children has own exit event that want to dispose some streams – Snake Eyes Jan 12 '21 at 09:07
  • 1
    So, graceful cancellation. Can child processes handle Ctrl+C? If so, just send Ctrl+C as shown here: https://stackoverflow.com/a/15281070/580053 – Dennis Jan 12 '21 at 09:19

0 Answers0