C/C++ - Не работает безопасное завершение дочерних процессов на C++

Ответить
Аватара пользователя
Макс1

C/C++ - Не работает безопасное завершение дочерних процессов на C++

Сообщение Макс1 »

Необходимо завершать процесс и все его дочерние процессы в программе на Microsoft Visual C++

Используется немного измененный код.

Функция SafeTerminateProcess для безопасного завершения процесса по этой ссылке.

http://hyacinth.byus.net/moniwiki/wi...rminateProcess


И функция 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;
}
Ответить

Вернуться в «Программирование и базы данных»