Witam,

Chciałbym by mój program miał możliwość przerwania określonego procesu.

Do tego celu próbuję użyć funkcji TerminateProcess.
Znajduję uchwyt do okna po nazwie okna, potem ID procesu, otwieram ten proces, no i próbuję zamknąć.
Jeśli określony proces jest uprzednio uruchomiony przez mój program, nie ma żadnego problemu, funkcja działa i wybrany proces ulega terminacji.
Jeżeli natomiast próbuję moim programem zamknąć proces który został uruchomiony np uprzednio ręcznie przeze mnie, po wywołaniu funkcji TerminateProcess zwraca błąd 5 ERROR_ACCESS_DENIED.

Próbowałem kombinować z nadawaniem przywilejów mojemu programowi poprzez *AdjustTokenPrivileges * przy czym:

  • zakończone sukcesem nadanie przywileju SE_DEBUG_NAME nie pomaga.
  • próba nadania procesowi mojego programu przywileju SE_TCB_NAME zwraca błąd 5 ERROR_ACCESS_DENIED.

Działam na Windows 7 Home Premium z SP1
Poniżej przykład tego z czego usiłuję skorzystać napisany w Visual Studio 2012 Express i dla przykładu windowsowego Kalkulatora:
Żeby nie zaciemniać trzy funkcje z których korzystam, wyciąłem z klas wrzuciłem do Main(); tak aby kto chętny mógł skompilować:

#include <windows.h>
#include <fstream>

using namespace std;
//=========Declarations=========//

ofstream plik; // do pliku wrzucamy wyniki z GetLastError

bool SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege); 

bool TerminateRunningProcess(LPCSTR name); 

bool RunProcess(LPSTR path); 

//======Main===================//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
  plik.open("Result.txt"); // Do pliku wrzucamy wyniki zwracane przez GetLastError
	
  SetPrivilege(/*SE_TCB_NAME*/ SE_DEBUG_NAME, true); // Ustawia przywileje dla bierzącego procesu

  //RunProcess("c:\\windows\\system32\\calc.exe"); // można odznaczyć i uruchomić kalkulator, wtedy program da radę go zamknać.

  TerminateRunningProcess("Kalkulator"); // Przerwij proces

}//==========MainEnd==========================//


//================Definitions=================//

bool SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)  // to enable or disable privilege
{
	
    HANDLE hToken; 
    OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken); //token do bieżącego procesu
    {
	DWORD result = GetLastError();
	plik << "OpenProcessToken_result: " << result << endl;
    }

    TOKEN_PRIVILEGES tp;
    LUID luid;

    LookupPrivilegeValue(NULL, lpszPrivilege, &luid);			
    {
        DWORD result = GetLastError();
	plik << "LookupPrivilegeValue_result: " << result << endl; 
	if (result != ERROR_SUCCESS)
		return result;
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;

    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;


    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL); 
    { 
        DWORD result = GetLastError();
	plik << "AdjustTokenPrivileges_result: " <<  result << endl; 
	if (result != ERROR_SUCCESS)
		return result;
    } 
    plik << "   Privileges Set Succesfully" << endl;
    return true;

};//======SetPrivilege_END=====//



bool TerminateRunningProcess(LPCSTR name)
{
	HWND windowHandle = FindWindow(NULL, name); // uchwyt do okna po nazwie
	{
		DWORD result = GetLastError();
		plik << "FindWindow_result: " << result << endl;
	}
	
	DWORD processID;
	GetWindowThreadProcessId(windowHandle, &processID); // ID procesu do zamknięcia po uchwycie okna
	{
		DWORD result = GetLastError();
		plik << "GetWindowThreadProcessId_result: " << result << endl;
	}

	HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS /*| PROCESS_TERMINATE */, FALSE, processID); // handle do do procesu 
	{
		DWORD result = GetLastError();
		plik << "OpenProcess_result: " << result << endl;
	}

	TerminateProcess(handle, NULL);
	{
		DWORD result = GetLastError();
		plik << "TerminateProcess_result: " << result << endl;
	}

	return true;

};//=====TerminateRunningProcess_END=====//

bool RunProcess(LPSTR path)
{
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
   
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
   
    CreateProcess(path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	{
		DWORD result = GetLastError();
		plik << "CreateProcess_result: " << result << endl;	
	}
	Sleep(3000);
	return true;
}; //=====RunProcess_END=======
 

Jeśli ktoś chciałby to uruchomić w VS 2012 Express to ja mam ustawione następujące opcje:

  • General > Character Set > Use Multibyte Character Set
  • General > Common Language Runtime Support > No Common Language Runtime Support
  • C/C++ > Precompiled Headers > Not Using Precompiled Headers
  • Linker > System > Subsystem > Not Set

Czy ktoś ma pomysł w jaki sposób umożliwić mojemu programowi terminację "obcego" procesu?
W jaki sposób nadać procesowi mojego programu przywilej SE_TCB_NAME?
Czy powyższe kwestie mogą być związane z tematem kontroli przywilejów Windows 7?

edit: trochę z wcięcia dziwnie poformatowało, poprawiłem by nie raziło w oczy.