using System.Globalization; using System.Runtime.InteropServices; namespace Geekeey.Extensions.Process.Win.Notify; internal static class Interop { public delegate bool ConsoleCtrlDelegate(uint dwCtrlEvent); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool FreeConsole(); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool AttachConsole(uint dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? handlerRoutine, bool add); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); } internal static class Program { public static int Main(string[] args) { var processId = uint.Parse(args[0], CultureInfo.InvariantCulture); var signal = uint.Parse(args[1], CultureInfo.InvariantCulture); // detach from the current console, if one is attached to the process. Interop.FreeConsole(); var success = // attach to the target process group Interop.AttachConsole(processId) && // set to ignore signals on self, so the proper exit code can be return Interop.SetConsoleCtrlHandler(null, true) && // send the signal to the process group Interop.GenerateConsoleCtrlEvent(signal, 0); return success ? 0 : Marshal.GetLastPInvokeError(); } }