SigIntHelper.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. namespace winsw
  7. {
  8. public static class SigIntHelper
  9. {
  10. private const string KERNEL32 = "kernel32.dll";
  11. [DllImport(KERNEL32, SetLastError = true)]
  12. private static extern bool AttachConsole(uint dwProcessId);
  13. [DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
  14. private static extern bool FreeConsole();
  15. [DllImport(KERNEL32)]
  16. private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
  17. // Delegate type to be used as the Handler Routine for SCCH
  18. private delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
  19. // Enumerated type for the control messages sent to the handler routine
  20. private enum CtrlTypes : uint
  21. {
  22. CTRL_C_EVENT = 0,
  23. CTRL_BREAK_EVENT,
  24. CTRL_CLOSE_EVENT,
  25. CTRL_LOGOFF_EVENT = 5,
  26. CTRL_SHUTDOWN_EVENT
  27. }
  28. [DllImport(KERNEL32)]
  29. [return: MarshalAs(UnmanagedType.Bool)]
  30. private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
  31. /// <summary>
  32. /// Uses the native funciton "AttachConsole" to attach the thread to the executing process to try to trigger a CTRL_C event (SIGINT). If the application
  33. /// doesn't honor the event and shut down gracefully, the. wait period will time out after 15 seconds.
  34. /// </summary>
  35. /// <param name="process">The process to attach to and send the SIGINT</param>
  36. /// <returns>True if the process shut down successfully to the SIGINT, false if it did not.</returns>
  37. public static bool SendSIGINTToProcess(Process process)
  38. {
  39. if (AttachConsole((uint)process.Id))
  40. {
  41. //Disable Ctrl-C handling for our program
  42. SetConsoleCtrlHandler(null, true);
  43. GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
  44. process.WaitForExit(15000);
  45. return process.HasExited;
  46. }
  47. else
  48. {
  49. return false;
  50. }
  51. }
  52. }
  53. }