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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9428456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:48:53  来源:igfitidea点击:

how to terminate a process created by CreateProcess()?

c++winapivisual-c++mfccreateprocess

提问by digvijay

I have created a process using CreateProcess(). This is the code:

我创建了一个使用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)

How can I get the Handle and processId of this specific process? And eventually use it to close this process?
Thank You.

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

采纳答案by HardCoder

In the struct piyou 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]
A handle to the process to be terminated.

The handle must have the PROCESS_TERMINATE access right. For more information, see Process Security and Access Rights.

uExitCode [in]
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. Use the GetExitCodeThread function to retrieve a thread's exit value.

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

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

uExitCode [in]
作为此调用的结果而终止的进程和线程将使用的退出代码。使用 GetExitCodeProcess 函数检索进程的退出值。使用 GetExitCodeThread 函数检索线程的退出值。

回答by hmjd

A handle to the process is returned in the PROCESS_INFORMATIONstructure, pivariable.

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

The TerminateProcess()function can be used to terminate the process. However, you should consider why you need to kill the process and why a graceful shutdown is not possible.

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

Note you need to set the cbmember of sibefore calling CreateProcess():

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

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 STARTUPINFOstructure prior to calling CreateProcess():

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

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

回答by vll

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. Many Windows applications respond to this message by shutting down.

    NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.

    Use EnumWindows() to find the handles to your target windows. In your callback function, check to see if the windows' process ID matches the process you want to shut down. You can do this by calling GetWindowThreadProcessId(). Once you have established a match, use PostMessage() or SendMessageTimeout() to post the WM_CLOSE message to the window.

  2. Use WaitForSingleObject() to wait for the handle of the process. Make sure you wait with a timeout value, because there are many situations in which the WM_CLOSE will not shut down the application. 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.

  3. If the return value is WAIT_OBJECT_0, then the application closed itself down cleanly. If the return value is WAIT_TIMEOUT, then you must use TerminateProcess() to shutdown the application.

    NOTE: If you are getting a return value from WaitForSingleObject() other then WAIT_OBJECT_0 or WAIT_TIMEOUT, use GetLastError() to determine the cause.

By following these steps, you give the application the best possible chance to shutdown cleanly (aside from IPC or user-intervention).

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

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

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

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

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

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

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

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

See this answer for code.

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

Terminating the process

终止进程

If you don't care about clean shutdown, you can use TerminateProcess(). However, it is important to note that TerminateProcess()is asynchronous; it initiates termination and returns immediately. If you need to be sure the process has terminated, call the WaitForSingleObject()function with a handle to the process.

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

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);

回答by juergen d

STARTUPINFOA siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);

DWORD dwExitCode = 0;
if (CreateProcess(prgName.c_str(),
                (LPSTR) parameters.c_str(), 
                0, 
                0, 
                false,
                CREATE_DEFAULT_ERROR_MODE, 
                0, 
                0,
                &siStartupInfo, 
                &piProcessInfo) != false)
{       
    dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (time_in_ms));
}
else
{        
    return GetLastError(); //return error or do smething else
}

CloseHandle(piProcessInfo.hProcess);
CloseHandle(piProcessInfo.hThread);

piProcessInfo.hProcessis the handle of the process.

piProcessInfo.hProcess是进程的句柄。

WaitForSingleObject: Waits until the specified object is in the signaled state or the time-out interval elapses.

WaitForSingleObject:等待指定对象处于信号状态或超时间隔结束。

After that (time_in_ms) the process will be closed.

之后 ( time_in_ms) 进程将被关闭。

回答by Benoit

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 pistructure.

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

In order to kill the process you can use TerminateProcess

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