![]() |
Programm beenden
Hi Leute!
Ich bin neu und noch etwas unerfahren. Aber ich hoffe, das ich hier trotzdem richtig bin mit meinem Anliegen. Ich will ein Programm mit einem bestimmten Namen,(blabla.exe) beenden. Gibt es da eine bestimmte Routine? mfg Moyyer :?: |
Hi Moyyer,
ich bin zwar auch neu auf dem Gebiet aber ich glaube nicht das das so ohne weiteres geht! Ich würde schon sagen, das man dafür das entsprechende Proggie verknüpfen muss etc. Aber nicht verzagen hier kriegt man meistens kompetente Antworten!!! 8) :wink: |
:wiejetzt: Das eigene oder ein fremdes Programm?
|
Zitat:
Zitat:
Ich hoffe mal das ich da auch richtig liege :wink: |
Hier steht ein Beispiel:
![]() |
Tach,
das würde jetzt ein aussenstehendes Programm schliessen richtig? Dann sollte er sich das mal zu Gemüte führen würde ich sagen ^^ |
Zitat:
|
Da haste nu auch wieder recht :wink:
|
Hallo und herzlich Willkommen in der Delphi-PRAXiS!!!
Du musst
Delphi-Quellcode:
aus
{******************************************************************************}
{** **} {** ProzessID an Hand der Exe-Datei ermittlen **} {** **} {******************************************************************************} function GetProcessID(sProcName: String): Integer; var hProcSnap: THandle; pe32: TProcessEntry32; begin result := -1; hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); if hProcSnap = INVALID_HANDLE_VALUE then exit; pe32.dwSize := SizeOf(ProcessEntry32); { wenn es geklappt hat } if Process32First(hProcSnap, pe32) = true then { und los geht's: Prozess suchen} while Process32Next(hProcSnap, pe32) = true do begin if pos(sProcName, pe32.szExeFile) <> 0then result := pe32.th32ProcessID; end; end; {******************************************************************************} {** **} {** Prozess beenden **} {** **} {******************************************************************************} procedure KillProcess(dwProcID: DWORD); var hProcess : Cardinal; dw : DWORD; begin { open the process and store the process-handle } hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID); { kill it } TerminateProcess(hProcess, 0); { TerminateProcess returns immediately, so wie have to verify the result via WaitfForSingleObject } dw := WaitForSingleObject(hProcess, 5000); case dw of { everythings's all right, we killed the process } WAIT_OBJECT_0: Messagebox(Application.Handle, 'Prozess wurde beendet.', 'Prozess beenden', MB_ICONINFORMATION); { process could not be terminated after 5 seconds } WAIT_TIMEOUT: begin Messagebox(Application.Handle, 'Prozess konnte nicht innerhalb von 5 Sekunden beendet werden.', 'Prozess beenden', MB_ICONSTOP); CloseHandle(hProcSnap); exit; end; { error in calling WaitForSingleObject } WAIT_FAILED: begin RaiseLastOSError; CloseHandle(hProcSnap); exit; end; end; CloseHandle(hProcSnap); { and refresh listbox contend } Form1.Button1Click(Form1); end; ![]() UND DAS GANZE SO AUFRUFEN:
Delphi-Quellcode:
Es ist nicht getestet, kann auch sein dass du den ganzen Pfad übergeben musch ...
KillProcess(GetProcessID('blabla.exe'));
|
Moin Moyyer,
erst einmal herzlich willkommen hier in der Delphi-PRAXiS. Falls das externe Programm mitspielt könnte man auch versuchen es durch das Senden von WM_CLOSE dazu zu bringen sich zu beenden. Beipiele hierfür solltest Du hier finden können. |
Bei "CloseHandle(hProcSnap);" kommt die Fehlermeldung, das hProcSnap ein undefinierter Bezeichner ist.
Aber ansonsten klingt es gut. :lol: |
Hoi, so wie ich das sehe hat Luckie da hProcess mit hProcSnap verwechselt ...
Hier noch mal der veränderte Code.
Delphi-Quellcode:
PS: Kanns immer noch ned testen ...
{******************************************************************************}
{** **} {** ProzessID an Hand der Exe-Datei ermittlen **} {** **} {******************************************************************************} function GetProcessID(sProcName: String): Integer; var hProcSnap: THandle; pe32: TProcessEntry32; begin result := -1; hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); if hProcSnap = INVALID_HANDLE_VALUE then exit; pe32.dwSize := SizeOf(ProcessEntry32); { wenn es geklappt hat } if Process32First(hProcSnap, pe32) = true then { und los geht's: Prozess suchen} while Process32Next(hProcSnap, pe32) = true do begin if pos(sProcName, pe32.szExeFile) <> 0then result := pe32.th32ProcessID; end; CloseHandle(hProcSnap); end; {******************************************************************************} {** **} {** Prozess beenden **} {** **} {******************************************************************************} procedure KillProcess(dwProcID: DWORD); var hProcess : Cardinal; dw : DWORD; begin { open the process and store the process-handle } hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID); { kill it } TerminateProcess(hProcess, 0); { TerminateProcess returns immediately, so wie have to verify the result via WaitfForSingleObject } dw := WaitForSingleObject(hProcess, 5000); case dw of { everythings's all right, we killed the process } WAIT_OBJECT_0: Messagebox(Application.Handle, 'Prozess wurde beendet.', 'Prozess beenden', MB_ICONINFORMATION); { process could not be terminated after 5 seconds } WAIT_TIMEOUT: begin Messagebox(Application.Handle, 'Prozess konnte nicht innerhalb von 5 Sekunden beendet werden.', 'Prozess beenden', MB_ICONSTOP); CloseHandle(hProcess); exit; end; { error in calling WaitForSingleObject } WAIT_FAILED: begin RaiseLastOSError; CloseHandle(hProcess); exit; end; end; CloseHandle(hProcess); end; |
Bei mir hat's funktioniert. Danke! :dancer:
Ich bin noch bei einem anderen forum, aber da kriegt man immer nur dumme Antworten. Hier sind alle viel netter111 |
Hoi,
schön das wir dir helfen konnten ... |
Eine Frage hab ich aber noch. Wie kann ich wenn mein Programm schon einmal gestartet ist das alte killen und das neue verwenden?
|
Also wie man nur eine Instanz laufen lassen kann steht in der Library
![]() |
Das mit dem nicht 2x starten ist klar.
Mein eigendliches anliegen ist: Ich öffne das 1. Programm(Audioplayer) mit Paramstr(...). Also eine MP3. Wenn ich eine andere MP3 auch so öffne sagt er mir,(so soll es auch sein) dass das Programm schon einmal offen ist. Nun will ich aber, dass das 1. Programm die Parameter erhält (abspielt) die sonst das 2.Programm (das was geschlossen wurde) erhalten hätte. Ich hoffe ihr versteht, was ich meine!!! |
Du müsstest halt, bevor du eine neue Datei aufmachst, den 1. Player auch beenden. Dann gibt es kein zweites Audioplayer Fenster mehr, sondern nur immer 1, weil das alte ja immer beendet wird.
|
und wie soll ich das machen außer auf das X zu klicken :?:
|
Moin Moyyer,
spielst Du die Datei in Deinem Programm ab, oder mit einem externen? |
Zitat:
|
Wenn ichs über die ProcessID mach (Code von Luckie) dann bekommen beide Instanzen die gleiche ID :roll: :cry: :?:
|
Ich öffne die datei mut meinem programm. Ich will nur eine instanz von meinem programm haben. Wenn ein zweites geöffnet wird soll es die parameter an das erste schicken und danach beenden werde. gibt es da eine funktion?
Ich kenn mich da überhaupt nicht aus! :oops: |
Wenn ich alles richtig verstanden habe, dann müsste das folgendermaßen zu lösen sein:
Du könntest mit der Funktion versuchen, das Fenster zu beenden. Wenn das Programm nicht beendet werden kann, brauchst du es nicht zu beenden, weil es nicht geöffnet ist. Du brauchst somit nur diese Prozedur in die OnCreate-Routine einfügen. |
welche Prozedur soll ich in die oncreate-routine einfügen?
|
Moin Moyyer,
so eine Abfrage ist am Besten in der Projektdatei (DPR) untergebracht. Such' mal hier im Forum nach Mutex und WM_COPYDATA. Da solltest Du einiges passendes finden. |
Ich habe mich über diese Funktion informiert, wie du es gesagt hast und hatte auch gleich das richtige gefunden.
IHR SEIT EINFACH SPITZE! Diese Funktion suche ich schon seit Monaten. Vielen Dank!!! :hello: :D :coder: |
Re: Programm beenden
Jetzt muss ich doch meinen Senf noch dazu geben. Also die Funktion 'TerminateProcess' wird eigentlich vom TaskManager verwendet um z.B. ein abgestürztes Programm zu beenden, ist also das ultimative killen eines Prozesses. Manche Programme reagieren darauf unwirsch, z.B. beim nächsten Start mit der Meldung 'Programm wurde nicht korrekt beendet'. DLL's die von diesen Programmen verwendet werden, werden nicht korrekt beendet, sondern bleiben "offen". Das Verhalten kann man z.B. sehen wenn sich ein Programm im SysTray einnistet, das Icon bleibt in der Systray (verschwindet zwar wenn man mit der Maus drüberfährt). Also ich bezweifle, dass diese Funktion die richtige Art der Programmierung ist, insbesondere wenn man sie öfters verwendet. Leider weiss ich auch nichts Besseres. Eigentlich müsste nach der Literatur 'ExitProcess' das richtige sein. Aber die Funktion habe ich noch nicht recht verstanden, bis jetzt wurde nur immer mein eigenes Programm beendet. Trotz meiner vorigen 'klugen' Worte, wäre ich dankbar wenn jemand was Besseres weiss. :wall:
|
Re: Programm beenden
Moin Walter,
erst einmal herzlich willkommen hier in der Delphi-PRAXiS. Statt der "brutalen" Methode mit TerminateProcess könnte man auch versuchen, das Handle des Hauptfensters zu bekommen, und dorthin dann ein WM_CLOSE oder WM_SYSCOMMAND mit SC_CLOSE schicken. Das wäre fast so, als würde man das X anklicken. |
Re: Programm beenden
Hallo Christian,
erst mal danke für die Begrüssung u. die schnelle Antwort. Noch eine Frage hat ein Programm das sich nur in der SysTray einnistet (z.B einen Virenschutz) eigentlich auch ein Fensterhandle? (bevor ich umsonst rumprobiere). Gruss Walter PS Ich bin zwar aus Bayern, aber 'Moin, Moin' verstehe ich noch :thuimb: |
Re: Programm beenden
Moin Walter,
ein Fensterhandle sollte es haben, denn an dieses Fenster gehen auch die Nachrichten, wenn Du das Icon in der TBNA anklickst. Ob man das Programm auf dem genannten Weg schliessen kann ist dann wieder eine andere Sache ;-) |
Re: Programm beenden
Da du ExitProcess nicht sgaen kannst welchen Prozess es beenden soll, wirst du damit nie einen fremden Prozess beendne könne, sondern imme rnur den eigenen.
|
Re: Programm beenden
stell die frage in einem neue thread, da gibts mehr antworten aufgrund des entsprechenden topics... handle von anderem programm holen, dieses in den fordergrund holen, eigenes programm schließen... Geht am besten wenn du deinem mainform einen eindeutigen klassennamen gibst den kein anderes programm hat. Beim Thema mehrfachstart und parameterweitergabe gibts da nen beispiel dazu was allerdings bissl sehre viel zeilen beinhaltet... wenn du bei dem punkt nicht weiterkommst einfach nochmal posten, hab da bissl source dazu (8 zeilen oder so reichen da glaube schon)
|
Re: Programm beenden
Ich sehe schon, irgendwie scheint das Beenden von anderen Programmen (auf 'anständige' Weise) v. den Win-Entwicklern nicht gewollt zu sein, sonst würde es auch entsprechende eindeutige Funktionen geben und dieses Thema würde nicht soviel Diskussionsstoff hervorrufen. Für ExitProcess steht halt in der Referenz '....is the preferred method of ending a process...'. Ich hatte gedacht, dass man mit GetExitCodeProcess die entsprechenden Parameter bekommt. Jetzt muss ich halt weiter probieren. Sollte ich ein für mich zufriedenes Ergebnis erhalten, werde ich es natürlich hier posten, wenn Interesse besteht.
|
Re: Programm beenden
Zitat:
|
Re: Programm beenden
einfach an das entsprechende fenster wm_close senden, das ist doch nen vernünftiges beenden....
|
Re: Programm beenden
Mit dem WM_CLOSE ist ja in Ordnung (entspricht meiner Meinung nach der Tasturkombination ALT+F4). Die Tastaturkombination funktioniert aber nicht bei Programmen die sich in der TBNA eingenistet haben. Wie schon gesagt ich werde mich am Wochenende noch mal damit beschäftigen. (falls das Wetter schlecht ist :) )
|
Re: Programm beenden
ich habe mal den Code auf Seite 1 ausprobiert. Aber der funktioniert leider nicht. Folgende Meldungen gibt er mir immer:
[Error] main.pas(40): Undeclared identifier: 'TProcessEntry32' [Error] main.pas(43): Undeclared identifier: 'CreateToolHelp32SnapShot' [Error] main.pas(43): Undeclared identifier: 'TH32CS_SNAPPROCESS' [Error] main.pas(46): Missing operator or semicolon [Error] main.pas(46): Undeclared identifier: 'ProcessEntry32' [Error] main.pas(49): Undeclared identifier: 'Process32First' [Error] main.pas(51): Undeclared identifier: 'Process32Next' [Error] main.pas(53): Incompatible types [Error] main.pas(70): Undeclared identifier: 'hProcess' [Error] main.pas(70): Undeclared identifier: 'dwProcID' [Error] main.pas(75): Undeclared identifier: 'dw' [Warning] main.pas(89): Case label outside of range of case expression [Error] main.pas(102): Statement expected but 'PROCEDURE' found [Error] main.pas(114): Undeclared identifier: 'KillProcess' [Fatal Error] TimeGuard.dpr(5): Could not compile used unit 'main.pas' da ich leider nurAnfänger bin kann ich damit nix anfangen. Kann mir da bitte jemand helfen: :oops: |
Re: Programm beenden
Kuck mal in der Code-Lib, da findest du den vollständigen Code mit den erforderlichen Uses usw.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz