从服务启动EXE文件并通过发送SIGBREAK停止它

我写了一个启动java.exe或ruby.exe的服务(我知道有一些解决方案,但出于某些原因我需要自己的服务)。

到目前为止,服务工作找到了,我从注册表收集我的配置,然后启动服务。 当服务停止时,我得到我的进程并发送一个.Kill()。 到现在为止还挺好。 但我发现,.kill()是一个问题,因为ruby.exe(我使用thin启动服务)或java.exe(我用它启动SOLR)监听tcp套接字端口。 如果这个端口被使用并且我终止进程窗口将阻塞端口72秒(按设计)。

如果我执行solr:从shell命令shell启动并启动thin -start并使用Ctrl + C将其停止,则进程终止并且端口可立即使用。

所以我的猜测是:如果我设法向进程发送一个ctrl-c,它就会正确终止。

所以我发现这个post如何从exe服务运行exe并在exe进程退出时停止服务? 发布概念certificate的地方。 但是通过从窗口服务启动进程,我没有windowHandle。

我开始这样的服务:

m_process.StartInfo = new ProcessStartInfo { FileName = "java" , Arguments = arguments , UseShellExecute = true , WorkingDirectory = workDirectory , CreateNoWindow = false }; m_process.Start(); 

如果参数包含jetty数据以启动SOLR或者在ruby情况下我使用“ruby.exe thin start …”。

现在停止我尝试的服务:

 [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32")] public static extern int SetForegroundWindow(IntPtr hwnd); [DllImport("user32.dll", SetLastError = true)] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); foreach (int i in m_processList) { MyLogEvent(Process.GetProcessById(i).MainModule.ModuleName); MyLogEvent(Process.GetProcessById(i).MainWindowTitle); try { IntPtr ptr = FindWindow(null, Process.GetProcessById(i).MainWindowTitle); { SetForegroundWindow(ptr); Thread.Sleep(1000); InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.CANCEL); // SendKeys.Send("^{BREAK}"); Thread.Sleep(1000); } //Process.GetProcessById(i).Kill(); } catch(Exception ex) { MyLogEvent(ex.ToString()); Process.GetProcessById(i).Kill(); } } 

但由于我没有WindowTitle,我想我甚至没有窗口我无法分配这样的过程。

那么有谁知道如何分配过程并向其发送停止信号? 我可以忍受只是杀死进程,但这只是一个服务重新启动不可能没有等待很长时间。 感谢您提供任何提示,技巧和解决方案。

GenerateConsoleCtrlEvent可能有效

  m_process.StartInfo = new ProcessStartInfo { FileName = "java" , Arguments = arguments , UseShellExecute = true , WorkingDirectory = workDirectory , CreateNoWindow = false }; var process = m_process.Start(); 

什么时候杀儿童app …

  GenerateConsoleCtrlEvent(CTRL_C_EVENT, process.Id); 

成员声明

  public const UInt32 CTRL_C_EVENT = 0; [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);