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.