как завершить процесс, созданный CreateProcess ()?

Я создал процесс, используя CreateProcess(). Это код:

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:APDatabaseBasedbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:ADPSQLBase", &si, &pi)

Как я могу получить ручку и processId этого конкретного процесса? И в конце концов использовать его, чтобы закрыть этот процесс?
спасибо.

5 ответов


в структуре 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 для получения значения выхода потока.


дескриптор процесса возвращается в PROCESS_INFORMATION структуры pi переменной.

на TerminateProcess () функция может использоваться для завершения процесса. Тем не менее, вы должны рассмотреть, почему вам нужно убить процесс и почему изящное завершение работы невозможно.

Примечание вам нужно установить cb член si перед вызовом CreateProcess():

si.cb = sizeof(STARTUPINFO);

EDIT:

для подавления окно консоли укажите CREATE_NO_WINDOW, как флаг создания (шестой аргумент) в CreateProcess() звонок.

EDIT (2):

чтобы подавить окно, попробуйте установить следующие члены STARTUPINFO структура до вызова CreateProcess():

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

Это подробно объясняется в MSDN:

Если результат не равен нулю (что означает, что он удался), вы получите дескриптор и processid в pi структура.

чтобы убить процесс, вы можете использовать TerminateProcess


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) процесс будет закрыт.


закрытие процесса чисто

чтобы закрыть процесс чисто, вы должны сначала отправить сигнал закрытия:

как завершить приложение "чисто" в Win32.

Если вам абсолютно необходимо завершить процесс, выполните следующие действия:

  1. опубликовать WM_CLOSE для всех окон верхнего уровня, принадлежащих процессу, который вы хотите закрыть. Многие приложения Windows отвечают на это сообщение закрытием вниз.

    Примечание: ответ консольного приложения на WM_CLOSE зависит от того, установлен ли обработчик управления.

    используйте EnumWindows (), чтобы найти дескрипторы для целевых окон. В функции обратного вызова проверьте, соответствует ли идентификатор процесса windows процессу, который вы хотите закрыть. Это можно сделать, вызвав 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 или вмешательства пользователя).

см. этот ответ для кода.

завершить процесс

если вы не заботитесь о чистоте выключения, вы можете использовать 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);