简体   繁体   English

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

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

I have created a process using CreateProcess() .我使用CreateProcess()创建了一个进程。 This is the code:这是代码:

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)

How can I get the Handle and processId of this specific process?如何获取此特定进程的 Handle 和 processId? And eventually use it to close this process?并最终用它来关闭这个进程?
Thank You.谢谢。

In the struct pi you get:在结构pi你得到:

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

The first parameter is the handle to the process.第一个参数是进程的句柄。

You can use that handle to end the process : 您可以使用该句柄来结束该过程

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

hProcess [in] hProcess [输入]
A handle to the process to be terminated.要终止的进程的句柄。

The handle must have the PROCESS_TERMINATE access right.句柄必须具有 PROCESS_TERMINATE 访问权限。 For more information, see Process Security and Access Rights.有关更多信息,请参阅进程安全和访问权限。

uExitCode [in] uExitCode [输入]
The exit code to be used by the process and threads terminated as a result of this call.由于此调用而终止的进程和线程使用的退出代码。 Use the GetExitCodeProcess function to retrieve a process's exit value.使用 GetExitCodeProcess 函数检索进程的退出值。 Use the GetExitCodeThread function to retrieve a thread's exit value.使用 GetExitCodeThread 函数检索线程的退出值。

A handle to the process is returned in the PROCESS_INFORMATION structure, pi variable.进程的句柄在PROCESS_INFORMATION结构pi变量中返回。

The TerminateProcess() function can be used to terminate the process. TerminateProcess()函数可用于终止进程。 However, you should consider why you need to kill the process and why a graceful shutdown is not possible.但是,您应该考虑为什么需要终止进程以及为什么无法正常关闭。

Note you need to set the cb member of si before calling CreateProcess() :请注意,您需要在调用CreateProcess()之前设置sicb成员:

si.cb = sizeof(STARTUPINFO);

EDIT:编辑:

To suppress the console window specify CREATE_NO_WINDOW , as the creation flag (the sixth argument) in the CreateProcess() call.要取消控制台窗口,请指定CREATE_NO_WINDOW作为CreateProcess()调用中的创建标志(第六个参数)。

EDIT (2):编辑(2):

To suppress the window try setting following members of STARTUPINFO structure prior to calling CreateProcess() :要抑制窗口,请在调用CreateProcess()之前尝试设置STARTUPINFO结构的以下成员:

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

Closing the process cleanly干净地关闭进程

To close the process cleanly, you should send a close signal first:要干净地关闭进程,您应该首先发送关闭信号:

How To Terminate an Application "Cleanly" in Win32.如何在 Win32 中“干净地”终止应用程序。

If you absolutely must shut down a process, follow these steps:如果您绝对必须关闭某个进程,请执行以下步骤:

  1. Post a WM_CLOSE to all Top-Level windows owned by the process that you want to shut down.向要关闭的进程拥有的所有顶级窗口发布 WM_CLOSE。 Many Windows applications respond to this message by shutting down.许多 Windows 应用程序通过关闭来响应此消息。

NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.注意:控制台应用程序对 WM_CLOSE 的响应取决于它是否安装了控制处理程序。

Use EnumWindows() to find the handles to your target windows.使用 EnumWindows() 查找目标窗口的句柄。 In your callback function, check to see if the windows' process ID matches the process you want to shut down.在您的回调函数中,检查 Windows 的进程 ID 是否与您要关闭的进程匹配。 You can do this by calling GetWindowThreadProcessId().您可以通过调用 GetWindowThreadProcessId() 来完成此操作。 Once you have established a match, use PostMessage() or SendMessageTimeout() to post the WM_CLOSE message to the window.建立匹配后,使用 PostMessage() 或 SendMessageTimeout() 将 WM_CLOSE 消息发布到窗口。

  1. Use WaitForSingleObject() to wait for the handle of the process.使用 WaitForSingleObject() 等待进程的句柄。 Make sure you wait with a timeout value, because there are many situations in which the WM_CLOSE will not shut down the application.确保使用超时值等待,因为在很多情况下 WM_CLOSE 不会关闭应用程序。 Remember to make the timeout long enough (either with WaitForSingleObject(), or with SendMessageTimeout()) so that a user can respond to any dialog boxes that were created in response to the WM_CLOSE message.请记住使超时时间足够长(使用 WaitForSingleObject() 或使用 SendMessageTimeout()),以便用户可以响应为响应 WM_CLOSE 消息而创建的任何对话框。

  2. If the return value is WAIT_OBJECT_0, then the application closed itself down cleanly.如果返回值是 WAIT_OBJECT_0,则应用程序将自己彻底关闭。 If the return value is WAIT_TIMEOUT, then you must use TerminateProcess() to shutdown the application.如果返回值为 WAIT_TIMEOUT,则必须使用 TerminateProcess() 关闭应用程序。

NOTE: If you are getting a return value from WaitForSingleObject() other then WAIT_OBJECT_0 or WAIT_TIMEOUT, use GetLastError() to determine the cause.注意:如果您从 WaitForSingleObject() 获得除 WAIT_OBJECT_0 或 WAIT_TIMEOUT 之外的返回值,请使用 GetLastError() 确定原因。

By following these steps, you give the application the best possible chance to shutdown cleanly (aside from IPC or user-intervention).通过遵循这些步骤,您可以给应用程序最好的机会彻底关闭(除了 IPC 或用户干预)。

See this answer for code.请参阅此答案以获取代码。

Terminating the process终止进程

If you don't care about clean shutdown, you can use TerminateProcess() .如果您不关心干净关闭,则可以使用TerminateProcess() However, it is important to note that TerminateProcess() is asynchronous;但是,重要的是要注意TerminateProcess()是异步的; it initiates termination and returns immediately.它启动终止并立即返回。 If you have to be sure the process has terminated, call the WaitForSingleObject() function with a handle to the process.如果必须确保进程已终止,请使用进程句柄调用WaitForSingleObject()函数。

Note: Access rights PROCESS_TERMINATE and SYNCHRONIZE are required.注意:需要访问权限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);

Not closing, just wait until finished不关闭,等完成

If the process will finish on its own, instead of terminating you can wait until it has finished.如果进程将自行完成,您可以等待它完成而不是终止。

WaitForSingleObject(pi.hProcess, INFINITE);

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

This is explained thoroughly in MSDN :这在MSDN 中有详细解释:

If result is non-zero (which means that it succeeded) you will get the handle and processid in the pi structure .如果 result 非零(这意味着它成功了),您将在pi结构中获得句柄和 processid 。

In order to kill the process you can use TerminateProcess为了终止进程,您可以使用TerminateProcess

I have created a process using CreateProcess() .我已经使用CreateProcess()创建了一个进程。 This is the code:这是代码:

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)

How can I get the Handle and processId of this specific process?如何获取此特定过程的Handle和processId? And eventually use it to close this process?并最终使用它来关闭此过程?
Thank You.谢谢你。

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

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