004
04.04.2005, 16:27 Uhr
Spacelord
Hoffnungsloser Fall
|
Am saubersten ist es immer noch ne WM_CLOSE Message an das Hauptfenster der Anwendung zu schicken. Sofern diese aber kein Fenster hat kann man,etwas tricky, auch ExitProcess in einem fremden Prozess benutzen und somit werden schon mal die Dll´s über den "Tod" des Prozesses informiert. Vor einiger Zeit hatte ich mal etwas Code geschrieben der das erledigt.Sollte eigentlich für die FAQ werden hatte dann aber keine Zeit mehr dafür. Ich weiss jetzt auf Anhieb nicht mehr ob der Code schon "fertig" war oder ob ich da noch was machen wollte!? Naja,wer Fehler findet darf sie behalten
C++: |
#include <iostream> #include <windows.h> #include <tlhelp32.h>
const int EXIT_PROCESS_EX=1234; const int EXIT_BRUTAL = 4321;
int UI_GetProcId(); void DisplayProcesses(); bool ExitProcessEx(int,int= EXIT_PROCESS_EX); HANDLE GetProcessHandle(int); bool GetDebugPrivilege(bool);
int main() { DisplayProcesses(); ExitProcessEx(UI_GetProcId()); return 0; }
void DisplayProcesses() {
HANDLE hSnap = NULL; PROCESSENTRY32 proc; proc.dwSize = sizeof(proc); hSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ); Process32First(hSnap,&proc); proc.dwSize = sizeof(proc); do { printf("Prozess ID:%5d \t Name der Datei:%s \n",proc.th32ProcessID,proc.szExeFile);
}while(Process32Next(hSnap,&proc));
if(hSnap) CloseHandle(hSnap); }
int UI_GetProcId() { int temp=0; std::cout<<"Welcher Prozess soll beendet werden? \nID:"; std::cin>>temp;
return temp; }
bool ExitProcessEx(int id,int exitCode) { bool ok=false; HANDLE hProcess=NULL; HANDLE hThread=NULL; if((hProcess=GetProcessHandle(id))==NULL) return ok; else { PTHREAD_START_ROUTINE exitFunc=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"),"ExitProcess"); if(exitFunc==NULL) return ok;
hThread=CreateRemoteThread(hProcess,NULL,0,exitFunc,(LPVOID)exitCode,0,NULL); if(hThread==NULL) return ok;
DWORD result = WaitForSingleObject(hProcess,INFINITE); DWORD ex=0; switch(result) { case WAIT_OBJECT_0: GetExitCodeProcess(hProcess,&ex); if(ex!=STILL_ACTIVE ) printf("Das Programm wurde mit ExitCode %d beendet!\n",ex); break;
case WAIT_FAILED: printf("WFSO ist fehlgeschlagen!\nWarte 5 sek."); Sleep(5000); GetExitCodeProcess(hProcess,&ex); if(ex!=STILL_ACTIVE ) printf("Das Programm wurde mit ExitCode %d beendet!\n",ex); else { printf("Das Programm wurde immer noch nicht beendet!\nIch greife zu anderen Mitteln!!"); TerminateProcess(hProcess,EXIT_BRUTAL); } break; }
if(hThread!=NULL) CloseHandle(hThread); if(hProcess!=NULL) CloseHandle(hProcess); } return ok; }
HANDLE GetProcessHandle(int processID) { HANDLE pHandle=NULL; GetDebugPrivilege(true); pHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID); GetDebugPrivilege(false); return pHandle; }
bool GetDebugPrivilege(bool enable) { bool done=false; HANDLE processToken; if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&processToken)) { TOKEN_PRIVILEGES tp; tp.PrivilegeCount=1; LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid); tp.Privileges[0].Attributes= enable ? SE_PRIVILEGE_ENABLED : 0; AdjustTokenPrivileges(processToken,FALSE,&tp,sizeof(tp),NULL,NULL);
done=(GetLastError()==ERROR_SUCCESS);
CloseHandle(processToken); } return done; }
|
Dieser Code beendet durch das Debug Privileg jeden Prozess(auch Systemprozesse!) mit ExitProcess,was schonmal um einiges besser ist als TerminateProcess.
Funktioniert natürlich nicht unter 9x/ME weil da die Hälfte der verwendeten API´s keine geeignete Implementierung hatt.
Neuere Windowsversionen haben nen Tool dabei tskkill.exe(oder so) dass dafür gedacht ist fremde Prozesse zu beenden.Damit hab ich mich aber noch nicht beschäftigt und kann auch nicht sagen in wieweit die Prozesse sauber beendet werden.
MfG Spacelord -- .....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes. |