/NougakuDoCompanion/NougakudoLauncher/Startup.cs

# · C# · 148 lines · 101 code · 30 blank · 17 comment · 7 complexity · 61827be392f85b5e0dee0f23289d18bc MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using System.Runtime.InteropServices;
  9. namespace NougakudoLauncher
  10. {
  11. class Startup
  12. {
  13. Process rubyProcess;
  14. StreamWriter rubyWriter;
  15. StreamReader rubyReader;
  16. FileSystemWatcher signalWatcher;
  17. public bool Run(string ruby, string args, string environment)
  18. {
  19. ProcessStartInfo procInfo = new ProcessStartInfo(ruby);
  20. procInfo.Arguments = args;
  21. // BUNDLE_GEMFILE environment parameter
  22. if (environment != "")
  23. {
  24. var bundle = environment.Split('=');
  25. procInfo.EnvironmentVariables[bundle[0]] = bundle[1];
  26. }
  27. procInfo.UseShellExecute = false;
  28. procInfo.RedirectStandardOutput = true;
  29. procInfo.RedirectStandardInput = true;
  30. rubyProcess = new Process();
  31. rubyProcess.StartInfo = procInfo;
  32. rubyProcess.OutputDataReceived += new DataReceivedEventHandler(rubyProcess_OutputDataReceived);
  33. SetSignalWatcher();
  34. Console.WriteLine("Startup:Ruby Start");
  35. rubyProcess.Start();
  36. rubyProcess.BeginOutputReadLine();
  37. //rubyReader = rubyProcess.StandardOutput;
  38. Logging.Write("Startup:Nougakudo ruby process({1}) start by PID={0}.", new object[] { GetProcessId(), rubyProcess.Id }, Logging.LogType.INFO);
  39. //rubyWriter = rubyProcess.StandardInput;
  40. Console.WriteLine("Ruby process wait");
  41. rubyProcess.WaitForExit();
  42. int exitCode = rubyProcess.ExitCode; // Add ErrorCode
  43. Console.WriteLine("Ruby process exit");
  44. rubyProcess.Close();
  45. if (exitCode == 0) // Add ruby start error.
  46. return true; // Normal end
  47. else
  48. return false; // Error
  49. }
  50. string GetProcessId()
  51. {
  52. return Process.GetCurrentProcess().Id.ToString();
  53. }
  54. void SetSignalWatcher()
  55. {
  56. signalWatcher = new System.IO.FileSystemWatcher(".", GetProcessId() + ".*");
  57. signalWatcher.Created += new System.IO.FileSystemEventHandler(signalWatcher_Created);
  58. signalWatcher.EnableRaisingEvents = true;
  59. Logging.Write("Startup:Start to observe a terminate request.", Logging.LogType.INFO);
  60. }
  61. void signalWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
  62. {
  63. Logging.Write("Startup:Received a terminate request.", Logging.LogType.INFO);
  64. while (true)
  65. {
  66. try
  67. {
  68. if (File.Exists(e.FullPath))
  69. File.Delete(e.Name);
  70. break;
  71. }
  72. catch (Exception ex)
  73. {
  74. Logging.Write("Startup:terminate file delete error:" + ex.Message, Logging.LogType.WARNING);
  75. }
  76. Thread.Sleep(500);
  77. }
  78. SendTerminate();
  79. }
  80. void rubyProcess_OutputDataReceived(object sender, DataReceivedEventArgs outLine)
  81. {
  82. Logging.Write("OutputDataRec:" + outLine.Data, Logging.LogType.INFO);
  83. //Console.WriteLine("Redirect: {0}", outLine.Data);
  84. }
  85. //public void Read_StandardIO()
  86. //{
  87. // var sr = (TextReader)rubyReader;
  88. // if (rubyReader.EndOfStream)
  89. // {
  90. // Console.WriteLine("No Stream");
  91. // }
  92. // else
  93. // {
  94. // var d = sr.ReadToEnd();
  95. // Console.WriteLine("hhhh:{0}", d);
  96. // }
  97. //}
  98. public void SendTerminate()
  99. {
  100. Logging.Write("Startup:Generate a terminate request.", Logging.LogType.INFO);
  101. var ret = GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, 0);
  102. if (ret)
  103. Console.WriteLine("GenerateConsoleCtrlEvent true");
  104. else
  105. Console.WriteLine(Marshal.GetLastWin32Error().ToString());
  106. }
  107. [DllImport("kernel32.dll", SetLastError=true)]
  108. static extern bool GenerateConsoleCtrlEvent(ConsoleCtrlEvent sigevent, int dwProcessGroupId);
  109. public enum ConsoleCtrlEvent
  110. {
  111. CTRL_C = 0,
  112. CTRL_BREAK = 1,
  113. CTRL_CLOSE = 2,
  114. CTRL_LOGOFF = 5,
  115. CTRL_SHUTDOWN = 6
  116. }
  117. }
  118. }