HANDLE in HWND umwandeln ??
-
tsp schrieb:
Gegeben: HANDLE
Gesucht: HWND
Aktion: Ermittle über Prozessnamen das HANDLE und will mit SendMessage(hwnd,WM_CLose,...) den Prozess mit HWND beenden!Zunächst mal grundsätzliches :
Ein Betriebssystem kann 1 oder viele Prozesse haben.
Ein Prozess kann 1 oder viele Threads haben.
Ein Thread kann 0, 1 oder viele HWND's (Fenster) haben.Der Prozessname alleine ist einfach nicht eindeutig genug. Das musst Du bei folgendem Beispielcode immer im Hinterkopf haben :
// Ermittelt HWND's von Prozessen bei denen nur der "Name" bekannt ist #include <windows.h> #include <tlhelp32.h> BOOL CALLBACK EnumThreadWndProc ( HWND hwnd, LPARAM lParam ) { // Hier hast Du Zugriff auf die HWND's des Prozesses // Hier gilt : "Do At Your Own Risk" :-) Kleine Auswahl : // PostMessage (hwnd,WM_QUIT, 0,0); // PostMessage (hwnd,WM_CLOSE,0,0); // PostThreadMessage ((DWORD) lParam,WM_QUIT,0,0); // PostThreadMessage ((DWORD) lParam,WM_SYSCOMMAND,SC_CLOSE,0); return TRUE; } WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int) { TCHAR *cProcessName = "taskmgr.exe"; // der gesuchte Prozess HANDLE hSnapProcess; HANDLE hSnapThread; PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof (processInfo); THREADENTRY32 threadInfo; threadInfo.dwSize = sizeof (threadInfo); // 1. Alle Prozesse finden die cProcessName heissen hSnapProcess = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS,0); Process32First (hSnapProcess,&processInfo); do { // Wenn ein Prozess gefunden wurde, dann ... if ( !lstrcmpi (processInfo.szExeFile,cProcessName) ) { // nicht case-sensitive // 2. Alle Threads finden, die zu diesem Prozess gehören hSnapThread = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD,0); Thread32First (hSnapThread,&threadInfo); do { // Wenn ein Thread gefunden wurde, der zum Prozess gehört, dann ... if (threadInfo.th32OwnerProcessID == processInfo.th32ProcessID) { // 3. Alle HWND's via CALLBACK suchen, die zum Thread gehören EnumThreadWindows (threadInfo.th32ThreadID,(WNDENUMPROC) EnumThreadWndProc,threadInfo.th32ThreadID); } } while ( Thread32Next (hSnapThread,&threadInfo) ); CloseHandle (hSnapThread); } } while ( Process32Next (hSnapProcess,&processInfo) ); CloseHandle (hSnapProcess); return 0; }
-
...
// EDIT : versehentlich zweimal auf Absenden geklickt
...
-
Vielen Dank merker, hat mir sehr geholfen!
Aber ich hab doch noch mal die konkrete Frage:
Wie kann ich einen Prozess beenden???
(Gegeben: ProzessID, HANDLE)
Edit:
Ich hab mal ein bisschen probiert:
int isRun(string file) { HANDLE hSnapShot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof (processInfo); /*PROCESSENTRY32* processInfo = new PROCESSENTRY32; processInfo->dwSize = sizeof ( PROCESSENTRY32);*/ while ( Process32Next ( hSnapShot,&processInfo ) != FALSE) { if (strcmp(processInfo.szExeFile,file.c_str())==0)return processInfo.th32ProcessID; }; CloseHandle ( hSnapShot); //delete processInfo; return 0; } int main() { while (true) { Sleep(5); int i=isRun("notepad.exe"); if (i!=0) { LPDWORD lpd; HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,i); TerminateProcess(h,GetExitCodeProcess(h,lpd)); CloseHandle(h); } } return 0; }
Das klappt bei mir aber nicht! Es gibt zwar keine Fehlermeldung beim Kompilieren, aber beim Ausführen stürzt das Prog. immer ab! Warum?
-
tsp schrieb:
...aber beim Ausführen stürzt das Prog. immer ab! Warum?
GetExitCodeProcess () erwartet als 2. Parameter die Adresse eines DWORD's :
DWORD lpd; ... GetExitCodeProcess(h,&lpd)); ...
Falls strcmp () Gross- und Kleinschreibung beachtet, könnte es Probleme mit dem Prozessnamen geben ( -> notepad.exe != NOTEPAD.EXE <- ).
Deine main () enthält eine Endlosschleife. Willst Du verhindern, dass jemand notepad.exe startet ?tsp schrieb:
Wie kann ich einen Prozess beenden??? (Gegeben: ProzessID, HANDLE)
Dazu reicht die ProzessID :
DWORD dwProcessID = 1234; DWORD dwExitCode; HANDLE hProcess; // 3. Parameter : ProzessID (DWORD) hProcess = OpenProcess (PROCESS_ALL_ACCESS,FALSE,dwProcessID); // 1. Parameter : ProzessHANDLE (HANDLE), von OpenProcess () geliefert // 2. Parameter : ExitCode (kann selbst festgelegt werden, alle Zahlen erlaubt ausser STILL_ACTIVE) TerminateProcess (hProcess,12); // Aufruf nicht notwendig, da ja bekannt ist warum der Prozess beendet wurde :-) // Würde "12" als ExitCode liefern GetExitCodeProcess (hProcess,&dwExitCode); CloseHandle (hProcess);
-
MSDN schrieb:
he TerminateProcess function is used to unconditionally cause a process to exit. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.
TerminateProcess initiates termination and returns immediately. This stops execution of all threads within the process and requests cancellation of all pending I/O. The terminated process cannot exit until all pending I/O has been completed or canceled.
A process cannot prevent itself from being terminated.
Requirements
-
Vielen Dank!!
Jetzt funktioniert das mit TerminateProcess.
Aber ich musste leider wirklich feststellen, dass das mit TerminateProcess nicht so toll ist.Es bleiben immer Programmreste übrig, die Prozesse sind nie richtig beendet. Gibt es da nicht ne Möglichkeit (besser als TerminateProcess), alle Threads eines Prozesses mit zu beenden, sodass keine Reste mehr im Speicher sind (
so wie "Prozess beenden" im Task-Manager!) ?
-
www.webfritzi.de.vu --> WinAPI-Ecke --> Units --> Unit "AppTerminating"
-
tsp schrieb:
so wie "Prozess beenden" im Task-Manager
Der Task-Manager kocht auch nur mit Wasser :
DWORD dwProcessID = 1234; HANDLE hProcess; hProcess = OpenProcess (PROCESS_TERMINATE,false,dwProcessID); TerminateProcess (hProcess,1);
tsp schrieb:
Es bleiben immer Programmreste übrig, die Prozesse sind nie richtig beendet.
Das musst Du genauer beschreiben. Konnte TerminateProcess () einen Prozess nicht beenden ?
-
merker schrieb:
tsp schrieb:
Es bleiben immer Programmreste übrig, die Prozesse sind nie richtig beendet.
Das musst Du genauer beschreiben. Konnte TerminateProcess () einen Prozess nicht beenden?
Die DLLs bleiben geladen. Zitat MSDN: "The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess."
-
Hallo merker,
merker schrieb:
Das musst Du genauer beschreiben. Konnte TerminateProcess () einen Prozess nicht beenden ?
also: Ich habe zu Testzwecken notepad.exe beendet. Danach war trotzdem noch notepad.exe im task-Manager zu sehen, aber das verrückte war: Ich konnte den (Rest-)Prozess mit dem Task-Manager nicht mehr beenden!!!
-
Bist du denn jetzt weitergekommen mit deinem Problem?
-
Ja WebFritzi,
deine Funktionen funktionieren einwandfrei
, aber ich hätte doch gern noch gewusst, wie ich das selber in meinen Code einbauen kann.
-
Schau in meinen Code rein. Viel ist es ja nicht.
-
tsp schrieb:
Ich habe zu Testzwecken notepad.exe beendet. Danach war trotzdem noch notepad.exe im task-Manager zu sehen, ...
Passiert das ständig, öfters oder ganz selten, bzw. nur bei notepad.exe oder auch bei anderen Prozessen ?
-
@tsp: Du hast meinen Post aber bemerkt oder *grinz* ?
-
@merker:
Es passiert ständig bei jedem Prozess!
-
tsp schrieb:
Es passiert ständig bei jedem Prozess!
Poste nochmal die Schleife in der Du TerminateProcess () aufrufst.
Im Augenblick sorgst Du für eine mittelschwere Sensation :
TerminateProcess () erzeugt "Zombies" ?!?//EDIT : Nachtrag hinzugefügt
-
Hier noch mal die Loop:
int isRun(string file) { HANDLE hSnapShot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof (processInfo); /*PROCESSENTRY32* processInfo = new PROCESSENTRY32; processInfo->dwSize = sizeof ( PROCESSENTRY32);*/ while ( Process32Next ( hSnapShot,&processInfo ) != FALSE) { if (strcmpi(processInfo.szExeFile,file.c_str())==0)return rocessInfo.th32ProcessID; }; CloseHandle ( hSnapShot); //delete processInfo; return 0; } void lock(string file) { while (true) { Sleep(5); int i=isRun(file); if (i!=0) { TerminateAppByWindowClosing(i, 0); //HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,i); //TerminateProcess(h,12); //CloseHandle(h); } } } int main() { while (true) { Sleep(5); int i=isRun("notepad.exe"); if (i!=0) { HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,i); TerminateProcess(h,12); CloseHandle(h); } } return 0; }
Bitteschön.
-
Die Loop ist ok.
Wie hoch ist die Aktualisierungsgeschwindigkeit vom Taskmanager ?
-
Keine Ahnung, ich schätze mal so 10-100 ms.