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

时间:2012-02-24 09:37:34

标签: c++ winapi visual-c++ mfc 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?并最终用它来关闭这个过程? 谢谢。

5 个答案:

答案 0 :(得分:11)

PROCESS_INFORMATION结构pi变量中返回该流程的句柄。

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

请注意,在致电cb之前,您需要设置si的{​​{1}}成员:

CreateProcess()

编辑:

要取消控制台窗口,请指定si.cb = sizeof(STARTUPINFO); ,作为CREATE_NO_WINDOW来电中的creation flag(第六个参数)。

编辑(2):

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

CreateProcess()

答案 1 :(得分:10)

在结构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 [in]
  要终止进程的句柄。

     

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

     

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

答案 2 :(得分:1)

MSDN中详细解释了这一点:

如果结果为非零(这意味着它成功),您将获得pi structure中的句柄和processid。

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

答案 3 :(得分:1)

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.hProcess是该过程的句柄。

  

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

之后(time_in_ms),该过程将被关闭。

答案 4 :(得分:1)

干净地关闭进程

要完全关闭该过程,您应该先发送一个关闭信号:

How To Terminate an Application "Cleanly" in Win32.

  

如果您绝对必须关闭进程,请按照下列步骤操作:

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

         

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

         

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

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

  4.   
  5. 如果返回值为WAIT_OBJECT_0,则应用程序将完全关闭自身。如果返回值为WAIT_TIMEOUT,则必须使用TerminateProcess()关闭应用程序。

         

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

  6.   
     

通过执行以下步骤,可以为应用程序提供最佳的机会,使其彻底关闭(除了IPC或用户干预)。

See this answer for code.

终止过程

如果您不关心干净关机,则可以使用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);

不关闭,等到完成

如果该过程将自己完成,那么您可以等到完成为止,而不必终止。

WaitForSingleObject(pi.hProcess, INFINITE);

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