将 Ctrl+C 事件发送到在 Windows 上使用 QProcess 启动的进程

Posted

技术标签:

【中文标题】将 Ctrl+C 事件发送到在 Windows 上使用 QProcess 启动的进程【英文标题】:Sending Ctrl+C event to a process launched using QProcess on Windows 【发布时间】:2014-03-07 16:46:47 【问题描述】:

我有一个对话框,它充当控制台应用程序的配置器。对话框的工作是为用户提供一组小部件(反映控制台应用程序支持的选项),当用户单击“开始”按钮时,对话框会创建并启动一个 QProcess,其控制台应用程序的名称和参数基于GUI 中小部件的状态。我能够成功启动该过程,并且一切正常。但是,当我想终止进程时,控制台应用程序需要正常关闭,这意味着它必须关闭文件、刷新数据、关闭设备等,然后终止。

我使用了 QProcess::close(),这会立即杀死应用程序并且应用程序无法正常关闭。

我已使用 Win32 GenerateConsoleCtrlEvent(CTRL_C_EVENT, Q_PID::dwProcessId) 向同一设备发送偶数。我看到上面的 API 返回一个非零值(表示成功,失败时返回 0),但我的进程继续运行。

谁能帮助我如何通知 QProcess 正常关闭?或者有没有其他方法可以做到这一点?

【问题讨论】:

您确定有问题的应用程序实际上可以优雅地处理 Ctrl-C 吗?你有它的源代码吗? 是的。我的代码正在处理 Ctrl+C 和 Ctrl+Break 事件。 【参考方案1】:

GenerateConsoleCtrlEvent 采用进程 group id,而不是进程 id。您可能会为其提供一个进程 ID,因为这是 QProcess 提供的。

QProcess 目前不支持创建进程组。您需要使用 winapi 手动启动该过程,或者修补您的 Qt 副本以修改 qtbase/src/corelib/io/qprocess[.h,.cpp,_win.cpp] 以传递 CREATE_NEW_PROCESS_GROUP 创建标志。

如果您不想调整 Qt 本身,您可以将 qprocess 文件复制到您的项目中,重命名类,然后在其中添加更改。

【讨论】:

以上是关于将 Ctrl+C 事件发送到在 Windows 上使用 QProcess 启动的进程的主要内容,如果未能解决你的问题,请参考以下文章

将事件处理程序附加到在循环内创建的表单

将异步任务发送到在其他线程中运行的循环

在 Windows 上向 QProcess 发送 Ctrl+C

将 UDP 数据从 Windows 服务发送到同一台机器上运行网页的浏览器

如何将命令发送到在 perl 的非标准端口上运行的 telnet

将事件处理程序附加到在IFrame中呈现的HTML