在Windows上运行任意subprocess,仍然干净地终止?

我有一个应用程序A,我希望能够调用configuration文件中用户指定的任意其他进程

批处理脚本B是一个用户希望被A调用的进程.B设置一些环境variables,显示一些消息并调用编译器C来做一些工作。

Windows是否为任意进程提供了一个标准的方法来干净地终止? 假设A在控制台中运行并收到CTRL + C。 它可以传递给B和C吗? 假设A在窗口中运行,并且用户试图closures窗口,它可以取消B和C吗?

TerminateProcess是一个选项,但不是一个很好的select。 如果A在B上使用TerminateProcess,C继续运行。 如果C是长时间运行的,这可能会导致讨厌的问题,因为我们可能会启动另一个C实例来操作相同的文件,而C的第一个实例仍然在秘密工作。 此外,TerminateProcess不会导致干净的退出。

GenerateConsoleCtrlEvent听起来不错,当一切都在控制台中运行时,可能会工作,但文档说只能将CTRL + C发送到您自己的控制台,所以如果A在窗口中运行,将无法帮助。

在Windows上有没有和SIGINT等价的东西? 我很想find这样的文章: http : //www.cons.org/cracauer/sigint.html for Windows。

我想我在这个问题上有点晚了,但是对于有同样问题的人,我会写点东西。

我的问题是类似的,我希望我的应用程序是一个GUI应用程序,但执行的过程应该在后台运行,没有任何交互式控制台窗口附加。

我设法解决这个使用GenerateConsoleCtrlEvent()。 棘手的部分只是文档不清楚它如何使用以及它的缺陷。

我的解决方案是基于这里所描述的。 但是,这并没有真正解释所有的细节,所以这里是如何让它工作的细节。

  1. 创建一个新的帮助程序“Helper.exe”。 此应用程序将位于您的应用程序(父级)和您想要关闭的子进程之间。 它也将创建实际的子进程。 你必须有这个“中间人”过程或GenerateConsoleCtrlEvent()将失败。

  2. 使用某种IPC机制从父进程与辅助进程进行通信,帮助者应关闭子进程。 当帮助者得到这个事件时,它调用关闭自己和子进程的“GenerateConsoleCtrlEvent(CTRL_BREAK,0)”。 我为这个自己使用了一个事件对象,当它想要取消子进程时父进程完成。

要创建您的Helper.exe,请使用CREATE_NO_WINDOW和CREATE_NEW_PROCESS_GROUP进行创建。 而创建子进程时创建它没有标志(0),这意味着它将派生从它的父母的控制台。 不这样做会导致它忽略事件。

每一步都是这样完成是非常重要的。 我一直在尝试所有不同类型的组合,但是这个组合是唯一有效的组合。 您无法发送CTRL_C事件。 它将返回成功,但会被流程忽略。 CTRL_BREAK是唯一有效的工具。 这并不重要,因为他们最后都会调用ExitProcess()。

你也不能直接调用GenerateConsoleCtrlEvent()和子进程id的进程组id,直接允许helper进程继续生存。 这也会失败。

我花了一整天的时间试图让这个工作。 这个解决方案适用于我,但如果有人有任何其他的补充,请做。 我去了所有其他网络,发现了许多有类似问题的人,但没有明确的解决方案。 如何GenerateConsoleCtrlEvent()的作品也有点怪异,如果有人知道更多的细节,请分享。

正如@Shakta所说的GenerateConsoleCtrlEvent()是非常棘手的,但是你可以发送Ctrl + C而不需要帮助程序。

 void SendControlC(int pid) { AttachConsole(pid); // attach to process console SetConsoleCtrlHandler(NULL, TRUE); // disable Control+C handling for our app GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // generate Control+C event }