Maxhjk
Newbie | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Необходимо завершать процесс и все его дочерние процессы в программе на Microsoft Visual C++ Используется немного измененный код. Функция SafeTerminateProcess для безопасного завершения процесса по этой ссылке. http://hyacinth.byus.net/moniwiki/wiki.php/C%2B%2B/SafeTerminateProcess И функция KillProcessTree для рекурсивного завершения дочерних процессов по этой ссылке: http://www.cyberforum.ru/cpp-builder/thread1202071.html Если не удается завершить процесс с помощью функции SafeTerminateProcess, завершаю его с помощью функции TerminateProcess. Завершение процессов работает, но для дочерних процессов отладка показывает, что в большинстве случаев не работает функция SafeTerminateProcess, и в результате вызывается функция TerminateProcess. Для основного процесса SafeTerminateProcess всегда работает. Появляется одна из двух ошибок (если не было первой, в большинстве случаев появляется вторая). Функция GetExitCodeProcess получает ExitCode для дочернего процесса, равный нулю. Или бывает вторая ошибка hRT == null с ошибкой код 0x5 - Access Denied. Если сделать следующий код, вместо нее появляется ошибка Error unknown revision 0x519 Код: PSECURITY_DESCRIPTOR pSD; pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); SECURITY_ATTRIBUTES sa; sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = TRUE; hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess, &sa, 0, (LPTHREAD_START_ROUTINE)pfnExitProc, (PVOID)uExitCode, 0, &dwTID); | Если делать несколько попыток заврешения того же процесса с помощью SafeTerminateProcess, это не помогает. Можно ли исправить эти 2 ошибки и сделать, чтобы функция SafeTerminateProcess всегда завершала дочерние процессы? Код: BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode) { DWORD dwTID, dwCode, dwErr = 0; HANDLE hProcessDup = INVALID_HANDLE_VALUE; HANDLE hRT = NULL; HINSTANCE hKernel = GetModuleHandle(_T("kernel32")); BOOL bSuccess = FALSE; BOOL bDup = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcessDup, PROCESS_ALL_ACCESS, FALSE, 0); if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) && (dwCode == STILL_ACTIVE)) { FARPROC pfnExitProc; pfnExitProc = GetProcAddress(hKernel, "ExitProcess"); hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pfnExitProc, (PVOID)uExitCode, 0, &dwTID); if (hRT == NULL) dwErr = GetLastError(); } else { dwErr = ERROR_PROCESS_ABORTED; } if (hRT) { WaitForSingleObject((bDup) ? hProcessDup : hProcess, (DWORD) 10); CloseHandle(hRT); bSuccess = TRUE; } if (bDup) CloseHandle(hProcessDup); if (!bSuccess) SetLastError(dwErr); return bSuccess; } bool KillProcessTree(DWORD myprocID, DWORD dwTimeout) { bool bRet = true; HANDLE hWnd; PROCESSENTRY32 pe; memset(&pe, 0, sizeof(PROCESSENTRY32)); pe.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (Process32First(hSnap, &pe)) { BOOL bContinue = TRUE; while (bContinue) { if (pe.th32ParentProcessID == myprocID) { KillProcessTree(pe.th32ProcessID, dwTimeout); HANDLE hChildProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID); if (hChildProc) { if (WaitForSingleObject(hChildProc, dwTimeout) == WAIT_OBJECT_0) bRet = true; else { bRet = SafeTerminateProcess(hChildProc, 0); if (!bRet) bRet = TerminateProcess(hChildProc, 0); } CloseHandle(hChildProc); } } bContinue = Process32Next(hSnap, &pe); } HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID); if (hProc) { if (!SafeTerminateProcess(hProc, 0)) TerminateProcess(hProc, 0); CloseHandle(hProc); } } return bRet; } |
|