Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Programm beenden (https://www.delphipraxis.net/5289-programm-beenden.html)

Moyyer 31. Mai 2003 13:40


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 :?:

Wolverine 31. Mai 2003 13:49

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:

r_kerber 31. Mai 2003 13:49

:wiejetzt: Das eigene oder ein fremdes Programm?

Wolverine 31. Mai 2003 13:54

Zitat:

Zitat von r_kerber
:wiejetzt: Das eigene oder ein fremdes Programm?

Ich gehe mal Davon aus, das er ein fremdes Programm beenden möchte, da er folgendes geschrieben hat:

Zitat:

... Ich will ein Programm mit einem bestimmten Namen,(blabla.exe) beenden ...
Sonst hätte er wahrscheinlich "mein Programm" geschrieben.
Ich hoffe mal das ich da auch richtig liege :wink:

r_kerber 31. Mai 2003 13:58

Hier steht ein Beispiel: p.i.c.s. Delphi-Fundgrube

Wolverine 31. Mai 2003 14:00

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 ^^

r_kerber 31. Mai 2003 14:02

Zitat:

Zitat von horus
das würde jetzt ein aussenstehendes Programm schliessen richtig?

Korrekt. Ansonsten reicht ja ein Application.Terminate!

Wolverine 31. Mai 2003 14:04

Da haste nu auch wieder recht :wink:

RomanK 31. Mai 2003 14:24

Hallo und herzlich Willkommen in der Delphi-PRAXiS!!!

Du musst
Delphi-Quellcode:
{******************************************************************************} 
{**                                                                          **} 
{** 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;
aus diesem Post von Luckie Verwenden.
UND DAS GANZE SO AUFRUFEN:
Delphi-Quellcode:
KillProcess(GetProcessID('blabla.exe'));
Es ist nicht getestet, kann auch sein dass du den ganzen Pfad übergeben musch ...

Christian Seehase 31. Mai 2003 14:41

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.

Moyyer 31. Mai 2003 14:52

Bei "CloseHandle(hProcSnap);" kommt die Fehlermeldung, das hProcSnap ein undefinierter Bezeichner ist.

Aber ansonsten klingt es gut. :lol:

RomanK 31. Mai 2003 15:13

Hoi, so wie ich das sehe hat Luckie da hProcess mit hProcSnap verwechselt ...
Hier noch mal der veränderte Code.


Delphi-Quellcode:
{******************************************************************************} 
{**                                                                          **} 
{** 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;
PS: Kanns immer noch ned testen ...

Moyyer 31. Mai 2003 15:36

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

RomanK 31. Mai 2003 15:39

Hoi,
schön das wir dir helfen konnten ...

Moyyer 31. Mai 2003 16:22

Eine Frage hab ich aber noch. Wie kann ich wenn mein Programm schon einmal gestartet ist das alte killen und das neue verwenden?

RomanK 31. Mai 2003 17:03

Also wie man nur eine Instanz laufen lassen kann steht in der Library hier.

Moyyer 31. Mai 2003 19:25

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!!!

Stanlay Hanks 31. Mai 2003 19:28

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.

Moyyer 31. Mai 2003 21:37

und wie soll ich das machen außer auf das X zu klicken :?:

Christian Seehase 31. Mai 2003 22:50

Moin Moyyer,

spielst Du die Datei in Deinem Programm ab, oder mit einem externen?

Stanlay Hanks 1. Jun 2003 08:43

Zitat:

Zitat von Moyyer
und wie soll ich das machen außer auf das X zu klicken :?:

Es gibt hier im Forum viele Beiträge, wie man einen Prozess/ ein Programm beendet... (handle z.B)

RomanK 1. Jun 2003 10:34

Wenn ichs über die ProcessID mach (Code von Luckie) dann bekommen beide Instanzen die gleiche ID :roll: :cry: :?:

Moyyer 1. Jun 2003 12:16

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:

Illuminator-23-5 1. Jun 2003 12:35

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.

Moyyer 1. Jun 2003 12:40

welche Prozedur soll ich in die oncreate-routine einfügen?

Christian Seehase 1. Jun 2003 18:01

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.

Moyyer 1. Jun 2003 21:14

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:

Walter vdV 30. Okt 2003 20:03

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:

Christian Seehase 30. Okt 2003 20:10

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.

Walter vdV 30. Okt 2003 20:37

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:

Christian Seehase 30. Okt 2003 20:42

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 ;-)

Luckie 30. Okt 2003 20:42

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.

SirThornberry 30. Okt 2003 20:46

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)

Walter vdV 31. Okt 2003 08:14

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.

Luckie 31. Okt 2003 08:26

Re: Programm beenden
 
Zitat:

Zitat von Walter vdV
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.

Ja den eigenen. Rufst du die Methode Close von TForm auf, wird DElphi ganz zum Schluss auch ExitProcess aufrufen und den Prozess beenden.

SirThornberry 31. Okt 2003 08:59

Re: Programm beenden
 
einfach an das entsprechende fenster wm_close senden, das ist doch nen vernünftiges beenden....

Walter vdV 31. Okt 2003 09:38

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 :) )

GISS79 5. Mär 2004 21:01

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:

Luckie 5. Mär 2004 21:04

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