HANDLE in HWND umwandeln ??
-
Du kannst dir aber die HWNDs des Prozesses ausgeben lassen.
Ich weiß grad nicht (mehr welche API Funktion man das kann, aber es geht auf jeden Fall.
-
tsp schrieb:
Wir gehen einfach mal davon aus, dass der Prozess nur ein Fenster hat!
lol, ne machen wir nicht :p .
Also:
Du kannst mit der Funktion OpenProcess einen Handle auf einen Prozess ermitteln, dafür wird aber die ID benötigt... . Alternativ kannst Du alle verfügbaren Prozesse enumerieren (d.h. aufzählen), nämlich mit der Funktion CreateToolhelp32Snapshot. Mit der Funktion GetModuleFileName kannst Du Dir dann einen Pfad zum entsprechenden Handle holen und diesen ggf. vergleichen (lstrcmp). Da aber, wie ich schon sagte, ein Prozess mehrere Fenster haben kann und davon gehe ich jetzt auch einfach mal aus, da das eigentlich meistens so ist (außerdem ist die Vorgehensweise bei einem Prozess, der sicher nur ein Fenster hat gleich), ist Folgendes zu tun: Mit der Funktion EnumWindows kannst Du Dir, in Kombination mit einer von Dir definierten Funktion, deren Adresse dann an die Funktion EnumWindows übergeben wird ('callback'-Prinzip), alle existierenden Fenster enumerieren lassen. Um zu unterscheiden, welches Fenster nun zu einen bestimmten Prozess gehört, musst Du den Prozesshandle, den Du über OpenProcess/CreateToolhelp32Snapshot ermittelt hast, mit denen der Fenster vergleichen. Den Prozesshandle zu einem bestimmten Fenster bekommst Du über die Funktion GetWindowThreadProcessId in Kombination mit OpenProcess.
Wobei man diesen Weg auch andersrum beschreiten kann
.
Hoffe das hilft Dir.
-
Vielen Dank für eure Antworten,
hat vllt. jmd. mal ein Beispielcode (nur en Fetzen, muss nichts komplettes sein) ?
-
Glaube sowas ist zu spezifisch, da findeste keinen Beispielcode, vllt suchst Du mal bei www.koders.com, da findet man manchmal ganze Programme, wo soetwas zur Verwendung kommt
.
-
tsp schrieb:
hat vllt. jmd. mal ein Beispielcode ...
Formuliere Deine Frage mal im Sinne von "Gegeben / Gesucht / Aktion".
Beispiel :
Gegeben : Fensterhandle
Gesucht : ProzessID
Aktion : Prozess beenden
-
Hm...man kann aber nicht jede Frage auf so ein 'Muster' runterbrechen; nur so BTW.
-
Ok, für merker:
Gegeben: HANDLE
Gesucht: HWND
Aktion: Ermittle über Prozessnamen das HANDLE und will mit SendMessage(hwnd,WM_CLose,...) den Prozess mit HWND beenden!Für alle anderen: Neue Frage: Wie beende ich ein Prozess (HANDLE hab ich) ordentlich (also nicht mit TerminateProcess
klappt bei mir eh nich)
-
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.