繁体   English   中英

如何终止由 CreateProcess() 创建的进程?

[英]how to terminate a process created by CreateProcess()?

我使用CreateProcess()创建了一个进程。 这是代码:

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:\\AP\\DatabaseBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\ADP\\SQLBase", &si, &pi)

如何获取此特定进程的 Handle 和 processId? 并最终用它来关闭这个进程?
谢谢。

在结构pi你得到:

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD  dwProcessId;
    DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

第一个参数是进程的句柄。

您可以使用该句柄来结束该过程

BOOL WINAPI TerminateProcess(
    __in  HANDLE hProcess,
    __in  UINT uExitCode
);

hProcess [输入]
要终止的进程的句柄。

句柄必须具有 PROCESS_TERMINATE 访问权限。 有关更多信息,请参阅进程安全和访问权限。

uExitCode [输入]
由于此调用而终止的进程和线程使用的退出代码。 使用 GetExitCodeProcess 函数检索进程的退出值。 使用 GetExitCodeThread 函数检索线程的退出值。

进程的句柄在PROCESS_INFORMATION结构pi变量中返回。

TerminateProcess()函数可用于终止进程。 但是,您应该考虑为什么需要终止进程以及为什么无法正常关闭。

请注意,您需要在调用CreateProcess()之前设置sicb成员:

si.cb = sizeof(STARTUPINFO);

编辑:

要取消控制台窗口,请指定CREATE_NO_WINDOW作为CreateProcess()调用中的创建标志(第六个参数)。

编辑(2):

要抑制窗口,请在调用CreateProcess()之前尝试设置STARTUPINFO结构的以下成员:

STARTUPINFO si = {0};
si.cb          = sizeof(STARTUPINFO);
si.dwFlags     = STARTF_USESHOWWINDOW;
si.wShowWindow = FALSE;

干净地关闭进程

要干净地关闭进程,您应该首先发送关闭信号:

如何在 Win32 中“干净地”终止应用程序。

如果您绝对必须关闭某个进程,请执行以下步骤:

  1. 向要关闭的进程拥有的所有顶级窗口发布 WM_CLOSE。 许多 Windows 应用程序通过关闭来响应此消息。

注意:控制台应用程序对 WM_CLOSE 的响应取决于它是否安装了控制处理程序。

使用 EnumWindows() 查找目标窗口的句柄。 在您的回调函数中,检查 Windows 的进程 ID 是否与您要关闭的进程匹配。 您可以通过调用 GetWindowThreadProcessId() 来完成此操作。 建立匹配后,使用 PostMessage() 或 SendMessageTimeout() 将 WM_CLOSE 消息发布到窗口。

  1. 使用 WaitForSingleObject() 等待进程的句柄。 确保使用超时值等待,因为在很多情况下 WM_CLOSE 不会关闭应用程序。 请记住使超时时间足够长(使用 WaitForSingleObject() 或使用 SendMessageTimeout()),以便用户可以响应为响应 WM_CLOSE 消息而创建的任何对话框。

  2. 如果返回值是 WAIT_OBJECT_0,则应用程序将自己彻底关闭。 如果返回值为 WAIT_TIMEOUT,则必须使用 TerminateProcess() 关闭应用程序。

注意:如果您从 WaitForSingleObject() 获得除 WAIT_OBJECT_0 或 WAIT_TIMEOUT 之外的返回值,请使用 GetLastError() 确定原因。

通过遵循这些步骤,您可以给应用程序最好的机会彻底关闭(除了 IPC 或用户干预)。

请参阅此答案以获取代码。

终止进程

如果您不关心干净关闭,则可以使用TerminateProcess() 但是,重要的是要注意TerminateProcess()是异步的; 它启动终止并立即返回。 如果必须确保进程已终止,请使用进程句柄调用WaitForSingleObject()函数。

注意:需要访问权限PROCESS_TERMINATESYNCHRONIZE

TerminateProcess(pi.hProcess, 0);

// 500 ms timeout; use INFINITE for no timeout
const DWORD result = WaitForSingleObject(pi.hProcess, 500);
if (result == WAIT_OBJECT_0) {
    // Success
}
else {
    // Timed out or an error occurred
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

不关闭,等完成

如果进程将自行完成,您可以等待它完成而不是终止。

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

这在MSDN 中有详细解释:

如果 result 非零(这意味着它成功了),您将在pi结构中获得句柄和 processid 。

为了终止进程,您可以使用TerminateProcess

我已经使用CreateProcess()创建了一个进程。 这是代码:

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:\\AP\\DatabaseBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\ADP\\SQLBase", &si, &pi)

如何获取此特定过程的Handle和processId? 并最终使用它来关闭此过程?
谢谢你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM