【问题标题】:How can I gracefully stop a process created with CreateProcessW and option CREATE_NEW_CONSOLE?如何优雅地停止使用 CreateProcessW 和选项 CREATE_NEW_CONSOLE 创建的进程?
【发布时间】:2021-12-26 17:11:02
【问题描述】:

在我的应用程序的某个地方,我正在创建一个这样的流程:

STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(STARTUPINFO);

PROCESS_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(processInfo));

const auto created = CreateProcessW(
                        pathToExe,
                        cmdLine,
                        nullptr,
                        nullptr,
                        false,
                        CREATE_NEW_CONSOLE,
                        nullptr,
                        workingDir,
                        &startupInfo,
                        &processInfo);

我这里运行的exe是一个控制台应用程序。

稍后,我想优雅地停止该过程。我可以用TerminateProcess 杀死它,但我想让它更优雅,因为该进程可能需要将数据保存到某个数据库或执行一些清理操作(例如关闭硬件连接)。

我尝试使用EnumWindowsGetWindowThreadProcessId 获取进程HWND,但没有成功。事实上,EnumWindows 并没有列出我创建的进程。有了HWND,我的想法是发送WM_CLOSE 消息。

也许我不应该使用CREATE_NEW_CONSOLE 标志?我尝试了以下启动信息:

STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;

但这并没有向我显示控制台窗口(我需要拥有)。我究竟做错了什么?我应该如何创建我的流程,然后如何优雅地停止它?

【问题讨论】:

  • 有没有子进程的源码,可以修改一下吗?
  • 控制台应用程序是否需要某个组合键来告诉它退出? How to send a keystroke to an other process (ex a notepad)?
  • 您不能从外部优雅地终止进程。优雅终止需要合作。与通常响应和处理WM_CLOSE 请求的 GUI 应用程序不同,针对控制台子系统的进程不遵循允许从外部发送终止请求的通用方案。
  • EnumWindows 是错误的方法,终端/控制台窗口属于 csrss(旧 NT)或 conhost.exe,它不属于任何连接到控制台的进程。

标签: c++ winapi


【解决方案1】:

事实上,在我试图优雅地杀死我的控制台时,将HWND 发送到控制台窗口还为时过早。在一个测试中,我天真地创建了这个过程,然后几乎直接杀死了它。如果我等待的时间足够长(即如果我实际上与我创建的进程交互了一段时间),那么我可以获取控制台窗口的句柄并成功发送WM_CLOSE 消息。

【讨论】:

    猜你喜欢
    • 2020-04-07
    • 1970-01-01
    • 2016-11-16
    • 2019-11-10
    • 2011-03-12
    • 2011-01-04
    • 2023-03-22
    • 2021-06-04
    相关资源
    最近更新 更多