簡體   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