ShellExecute - Fenster wieder schliessen
-
TerminateProcess... doch nicht sooo brutal ;), WM_CLOSE ist doch viel besser :).
cya
-
Vielen Dank, doch einfach geht das nicht.
Ich kann es nicht einfach mit WM_CLOSE schliessen, da ich den Programmpfad und die Parameter erst zur Laufzeit angebe (Variable).
Und FinWindow hilft mir auch nicht viel weiter...da der Name nicht eindeutig ist und den Klassennname kann ich auch nicht angeben, da erst zur Laufzeit bekannt ist, um welche Anwendung es sich handeln soll.PS:
Meist ist es so, das ich den IE verwende (also IEFrame).
Allerdings will ich nicht einfach alle IEFrames schliessen, sondern nur genau das, welches geöffnet wurde.
Das ist das Problem.
-
Ich mache sowas wie folgt: Ich starte den Prozess nicht per ShellExecute(), sondern mit CreateProcess(). Da bekommt man nämlich im letzten Parameter die ProcessId. Zum Schließen des Prozesses öffne ich zuerst den Prozess:
// pID ist die Prozess-ID HANDLE hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pID);
Dann enumeriere ich alle Fenster (EnumWindows()) und frage in der EnumWindowsProc ab, ob das Fenster zu dem Prozess gehört (GetWindowThreadProcessId()). Wenn ja, hole ich mir das Owner-Window (GetWindow() mit GW_OWNER), also das Main-Window, und schließe es per WM_CLOSE und danach nochmal (um sicher zu gehen) mit WM_SYSCOMMAND und SC_CLOSE. Dann warte ich (wieder in der Ausgangsfunktion) auf das Schließen des Prozesses per WaitForSingleObject(). Bekomme ich kein Signal, verwende ich halt den Hammer: TerminateProcess(). Am Ende dann nochmal CloseHandle() mit dem Handle als Parameter, das ich von OpenProcess() zurückgegeben bekommen hatte.
[ Dieser Beitrag wurde am 11.03.2003 um 13:32 Uhr von WebFritzi editiert. ]
-
Wär das nicht auch was für die FAQ?
-
Vielen Dank erstmal für die Hilfe.
Boah...also ich habe vorher nur C++ in Konsole und ein ganz kleines bisschen im BCB4 (VCL) was gemacht.
Deshalb ist das jetzt ganz schön hart, was Du mir erzählst, WebFritzi.
Also, ich habe es Probiert und bin bei folg. Problem hängen geblieben:
Ich finde die ProcessID in pi nicht.
Laut Definition von ProcessInformation müsste das doch dwProcessID sein....char parameter[256]; char command[256]="c:\\programme\\internet explorer\\iexplore.exe "; strcpy(parameter,Edit1->Text.c_str()); strcat(command, parameter); TStartupInfo si; TProcessInformation pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); if(CreateProcess(NULL, command, NULL,NULL,false, CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL,"c:\\", &si, &pi)==false) Caption="Fehler beim Ausführen"; //Sleep(1000); HANDLE hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pi.dwProcessID);
-
Bekommst du einen Fehler, oder bekommst du einfach die ProcessID nicht?
-
Original erstellt von fit:
Laut Definition von ProcessInformation müsste das doch dwProcessID sein....[/code]Nein, sondern dwProcessId. In C(++) unterscheiden wir zwischen Klein- und Großschreibung. Und bitte benutze STARTUPINFO und PROCESS_INFORMATION statt den Borland-Struktur-Namen.
-
Original erstellt von flenders:
Wär das nicht auch was für die FAQ?Das muss der MOD entscheiden.
-
@WebFritzi: Wenn du Lust hast (fänd' ich gut) und du zu deinem Vorgehen noch einen schön kommentierten Code postest, fänd ich das eigentlich schon was für die FAQ
-
OK, werd ich heute abend machen. Jetzt muss ich erst mal los - ne neue Maus kaufen.
-
Wow, das wäre echt super.
Da kann ich mir ein Haufen Zeit beim endlosen Suchen, Übersetzen und Herumprobieren sparen.
WebFritzi braucht bestimmt nicht mal 15 Minuten für den Code...
-
Original erstellt von fit:
WebFritzi braucht bestimmt nicht mal 15 Minuten für den Code...Ne, ich hab ihn ja bei mir rumliegen. Muss ihn nur noch etwas anpassen. Hab jetzt übrigens ne neue Maus. Fühl mich wie neu geboren.
Naja, dann mal los:
// Ein paar Definitionen #define TA_FAILED 0 #define TA_SUCCESS_CLEAN 1 #define TA_SUCCESS_KILL 2 // Die WindowEnumProc zum Auffinden des Hauptfensters // des zu schließenden Prozesses BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) { static DWORD dwID; static HWND hwnd_Owner; GetWindowThreadProcessId(hwnd, &dwID); if(dwID == (DWORD)lParam) { hwnd_Owner = GetWindow(hwnd, GW_OWNER); if(!hwnd_Owner) // Das Fenster ist das oberste im Prozess { PostMessage(hwnd, WM_CLOSE, 0, 0); PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); return FALSE; // Nicht mehr weiter enumerieren } } return TRUE; } // Funktion zum Schließen des Haupt-Fensters des Prozesses WORD TerminateAppByWindowClosing(DWORD pID, DWORD dwTimeout) { HANDLE hProc; WORD wRet; // Wenn wir das Fenster nicht mit PROCESS_TERMINATE-Rechten, // schließen können, geben wir sofort auf hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pID); if(!hProc) return TA_FAILED; // Wir versuchen, den Prozess "clean" zu terminieren // durch Schließen des Haupt-Fensters EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM)pID); // Wir schauen, ob der Prozess geschlossen worden ist und warten // dabei dwTimeout Millisekunden if(WaitForSingleObject(hProc, dwTimeout) != WAIT_OBJECT_0) wRet = TA_FAILED; else wRet = TA_SUCCESS_CLEAN; CloseHandle(hProc); return wRet; } // Funktion zum Abwürgen des Prozesses // ACHTUNG: Alle DLLs, die mit dem Prozess verbunden sind, // werden nicht davon benachrichtigt, dass der Prozess // beendet wurde !!! WORD KillApp(DWORD pID) { HANDLE hProc; WORD wRet; // Wenn wir den Prozess nicht mit PROCESS_TERMINATE-Rechten // öffnen können, geben wir sofort auf hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pID); if(!hProc) return TA_FAILED; wRet = (WORD)( TerminateProcess(hProc,0) ? TA_SUCCESS_KILL : TA_FAILED ); CloseHandle(hProc); return wRet; }
Einen Prozess schließt du dann z.B. so:
INT resp; char* buf1 = "Der Prozess konnte nicht durch bloßes Schließen des\nFensters beendet werden. Wollen Sie ihn killen?"; char* buf2 = "Der Prozess konnte nicht gekillt werden"; if( TerminateAppByWindowClosing(pID, 10000) == TA_FAILED ) { resp = MessageBox(hwnd, buf1, "Information", MB_YESNO | MB_ICONINFORMATION); if(resp == IDYES) if(KillApp(pID) == TA_FAILED) MessageBox(hwnd, buf2, "Fehler", MB_OK|MB_ICONERROR); }
[ Dieser Beitrag wurde am 12.03.2003 um 21:01 Uhr von WebFritzi editiert. ]
-
Was war denn mit der Alten?
-
Ich hab's jetzt in die FAQ verschoben: ShellExecute - Fenster wieder schliessen
Ich hab auch gleich noch die unnützen Beitrage rausgeschmissen
-
@fit: Nimm nicht den Code in diesem Thread, sondern den in der FAQ. Den hab ich nämlich nochmal überarbeitet.
-
Hallo WebFritzi, was ist denn mit deiner alten Maus? Bitte gib mal ein kurzes Statement dazu ab!
-
OK, Vielen Dank nochmal !
Deine nächste Maus spendiere ich Dir, wenn Du mir weiterhin so viel hilfst.
PS: Gehe behutsam mit Deiner Deine Maus um.
@Killer: er hatte sicher ne mechanische Maus, die verdreckt war.
Ich hoffe mal, dass er sich ne optische gekauft hat, die >10 Jahre hält, falls es bis dahin überhaupt noch einen PS2-Anschluss gibt.[ Dieser Beitrag wurde am 12.03.2003 um 23:26 Uhr von fit editiert. ]
-
Original erstellt von <Killer>:
Hallo WebFritzi, was ist denn mit deiner alten Maus? Bitte gib mal ein kurzes Statement dazu ab!Die Maus ging nicht mehr richtig. Da hab ich sie kaputt gemacht.