【发布时间】:2014-12-11 20:23:54
【问题描述】:
我正在开发基于 boost.asio 的 HTTP 服务器。它应该在外部停止。我们使用 asio 信号处理,它对 ctrl-c 效果很好,但不处理 WM_CLOSE,因此没有直接的方法可以从外部优雅地关闭应用程序,例如通过taskkill。强制终止进程不是一种选择。有没有一种已知的方法来解决这个问题?
【问题讨论】:
-
您能否尝试使用
start "MyApp" myapp.exe启动您的应用程序,然后使用taskkill /FI "WINDOWTITLE eq MyApp*"向您的应用程序发送一个可以使用SetConsoleCtrlHandler设置的处理程序处理的事件(请参阅下面的答案)?这样你就杀死了包含cmd.exe,然后将CTRL_CLOSE_EVENT(IIRC)发送到你的应用程序。 -
谢谢!这也非常有用。有没有一种简单的方法可以隐藏控制台(不使用第三方实用程序)?如果不是,我想我可以编写一个简单的启动器,为我的进程创建一个新的隐藏控制台。
-
我希望 MSVC 将 CTRL_CLOSE_EVENT 映射到某个信号,以便 asio 可以捕获它,但显然这不会发生。尝试过 SIGINT、SIGTERM、SIGBREAK、SIGABRT、SIGABRT_COMPAT。有什么想法吗?
-
@DmitryShubin,MSVC 将 Ctrl+C 映射到
SIGINT,所有其他事件都映射到SIGBREAK。我刚刚使用通过signal安装的简单SIGBREAK处理程序进行了测试。这绝对可以处理CTRL_CLOSE_EVENT。问题是 taskkill.exe 只会将WM_CLOSE发送给控制台的有效所有者,由枚举窗口和调用GetWindowsThreadProcessId确定。通常这是分配控制台的进程,如果它仍在运行。但是关闭控制台也会杀死所有附加到它的进程;他们有 5 秒的时间干净地退出。
标签: c++ boost boost-asio windows-console taskkill