AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Ferngesteuertes Schließen einer Anwendung
Thema durchsuchen
Ansicht
Themen-Optionen

Ferngesteuertes Schließen einer Anwendung

Ein Thema von PremiumPils · begonnen am 10. Jan 2005 · letzter Beitrag vom 12. Jan 2005
Antwort Antwort
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#1

Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 01:11
Hallo Leute,

ich hab jetzt leider ien sporadisches Problem, wo ich auf eine Eingebung eurer seits hoffe. Ersteinmal viel Text... aber ich hoffe auf ein oder zwei Hinweise:

Ich habe ein kleines Testprogramm, welches mit Hilfe der Funktion "MyFunktionApplikationIstGestartet(MyHandle,MyEXE) ;" zu einer bestimmten EXE... zum Beispiel "project1.exe" über die Prozessliste das Window-Handle ermittelt. Dieses Handle verwende ich dann in einer Funktion, welche einstellbar lange periodisch versucht m.H. von "PostMessage(MyHandle, WM_CLOSE, 0, 0);" das Programm zu beenden.

Das alles funktioniert prima und anstandlos, wenn da nicht die Ausnahme wäre. Und zwar:

Bei einem Tester ist es so, dass für die zu beendende EXE das Handle richtig ermittelt werden, das Testprogramm also richtig feststellt, dass das zu beendende Programm gestartet ist. Das Programm ist entweder im Hindergrund (hat nicht den Focus - klar, ich hab ja gerade im Testprogramm geklickt) oder ist in der Taskbar minimiert.
Nun wird das Programm jedoch nicht wie bei mir und anderen beendet, sondern bleibt da. Kurios ist aber, dass das Programm beendet wird, wenn der Tester während der priodischen Versuche dem zu beendenden Programm den Focus gibt.

Ich steh auf dem Schlauch, und weiß nicht, wie ich dem zu beendenden Programm auf die Sprünge helfen kann!? Focus geben? Automatisch? Empfängt es die Nachricht ohen Focus? Help...

Euer
PremiumPils
  Mit Zitat antworten Zitat
Benutzerbild von Sprint
Sprint

Registriert seit: 18. Aug 2004
Ort: Edewecht
712 Beiträge
 
Delphi 5 Professional
 
#2

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 01:22
Zitat von PremiumPils:
welche einstellbar lange periodisch versucht m.H. von "PostMessage(MyHandle, WM_CLOSE, 0, 0);" das Programm zu beenden.
SendMessage(MyHandle, WM_SYSCOMMAND, SC_CLOSE, 0); Warum periodisch?
Ciao, Sprint.

"I don't know what I am doing, but I am sure I am having fun!"
  Mit Zitat antworten Zitat
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#3

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 02:03
Zitat:
Warum periodisch?
Hi, danke für die rasche Antwort, werd ich gleich mal ausprobieren - kurz bevor ich ruhen gehe.

Periodisch, weil das zu beendende Programm, nunja, wie schon angemerkt störisch ist. Und wenn es mehrere Fenster offen hat, hat dieses auch schon geholfen. Aber im Grunde hat sich dies daraus ergeben, da das Programm oftmals zwischen 5-20 Sekunden (je nach Datenvolumen) benötigt, um sich selber zu schließen. So lange wartet mein Programm - in der Zeit schick ich halt die Nachrichten raus.

Grüße,
PremiumPils
  Mit Zitat antworten Zitat
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#4

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 17:23
Die andere Procedure schließt bei mir zwar auch das Programm, jedoch beim "Sorgenkind".. der Ausnahme nicht. Gibt es eine andere Lösung, oder kennt jemand spezielle Rahmenbedingungen auf einem Win2000 System, die diese Nachrichten an das zu schließende Programm behindern?
  Mit Zitat antworten Zitat
Benutzerbild von Sprint
Sprint

Registriert seit: 18. Aug 2004
Ort: Edewecht
712 Beiträge
 
Delphi 5 Professional
 
#5

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 17:49
Zitat von PremiumPils:
Die andere Procedure schließt bei mir zwar auch das Programm, jedoch beim "Sorgenkind".. der Ausnahme nicht. Gibt es eine andere Lösung, oder kennt jemand spezielle Rahmenbedingungen auf einem Win2000 System, die diese Nachrichten an das zu schließende Programm behindern?
Kannst du die Anwendung über den "X" Button im Fenster schließen? Wenn ja, dann hast du das falsche Fensterhandle.
Ciao, Sprint.

"I don't know what I am doing, but I am sure I am having fun!"
  Mit Zitat antworten Zitat
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#6

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 19:54
Okay, also ich konnte jetzt was eingrenzen:

-den Wert in der INI auf 20 Sekunden stellen
-XYZ starten, wenn schon nicht
-mein Programm starten
-Auto Beenden = an
-Update starten, nun sollte XYZ ja beenden werden
-nun gleich mal XYZ den Fokus geben, also auf die Taskbar oder den Tray-Eintrag drücken

Antwort:
19:51 Bernd: XYZ is minimiert, wird nich beendet
19:51 Bernd: XYZ is im hintergrund maximiert ohne focus, wird beendet

Dieses verhalten wurde nun auch von jemanden anderes bestätigt. Nun gleich meine Frage, wie schicke ich an einen bestimmten Prozess, welcher gerade wohl kein Fenster hat (?!) eine Nachricht, das er beendet wird? Und wie stelle ich fest, ob der Prozess - eine bestimmte EXE gestartet ist?

verzweifelnd über sein unwissen,
PremiumPils
  Mit Zitat antworten Zitat
Benutzerbild von Sprint
Sprint

Registriert seit: 18. Aug 2004
Ort: Edewecht
712 Beiträge
 
Delphi 5 Professional
 
#7

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 23:16
Zitat von PremiumPils:
wie schicke ich an einen bestimmten Prozess, welcher gerade wohl kein Fenster hat (?!) eine Nachricht, das er beendet wird?
In dem du eine WM_QUIT Nachricht an den Thread schickst. Wie beendet man das Programm als Benutzer?

Zitat:
Und wie stelle ich fest, ob der Prozess - eine bestimmte EXE gestartet ist?
In dem du von jedem Prozess die Parent ProcessID mit dem Programm vergleichst.
Ciao, Sprint.

"I don't know what I am doing, but I am sure I am having fun!"
  Mit Zitat antworten Zitat
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#8

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 10. Jan 2005, 23:43
Zitat:
In dem du eine WM_QUIT Nachricht an den Thread schickst.
Beendet WM_QUIT, oder schließt es. Sprich, kommt der Thread noch dazu, seine Daten zu speichern?

Zitat:
Wie beendet man das Programm als Benutzer?
Ja - normal halt, da es sich um ein normales Delphi Windows Programm handelt, welches, wenn man es ins Tray minimiert im Task-Manager aus der Anwendungen-Liste verschwindet, und nur noch in der Prozesse-Liste ist. Dann funktioniert es wohl nicht mehr wie es soll.

Der Benutzer kann das Programm+zugehöriges Fenster mit einem klick auf das Tray-Icon wiederherstellen. Dann einfach nur noch auf das X im System Menu oben drücken, und es ist auch beendet.

Anbei einmal die beiden Funktionen, wie ich sie ursprünglich benutze:

Delphi-Quellcode:
function OwnFunctionAppKill2(MyEXE : string; MyWarteZeit:Integer) : boolean;
var
  MyHandle : HWND;
  MyZaehler : Integer;
begin
  Result := false;
  if OwnFunctionAppIsRunning2(MyHandle,MyEXE) then
  begin
    for MyZaehler := 1 to (MyWarteZeit * 4) do
    begin
      Sleep(250);
      Application.ProcessMessages;
      if not OwnFunctionAppIsRunning2(MyHandle,MyEXE) then
      begin
        Result := true;
        break;
      end
      else
      begin
        Result := false;
        PostMessage(MyHandle, WM_CLOSE, 0, 0);
      end;
    end;
  end
  else
  begin
    Result := true;
  end;
end;
{--------------------------------------------------------------------------------------------------------------}
{--------------------------------------------------------------------------------------------------------------}
function OwnFunctionAppIsRunning2(var MyHandle : HWND; MyEXE : String) : Boolean;
  function GetWindowByAppName(ApplicationName: String): Cardinal;
    function GetAppProcID(ApplicationName : String):Cardinal;
    var
      bContinue: BOOL;
      aSnapshotHandle: THandle;
      aProcessEntry32: TProcessEntry32;
    begin
      result := 0;
      aSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      aProcessEntry32.dwSize := SizeOf(aProcessEntry32);
      bContinue := Process32First(aSnapshotHandle, aProcessEntry32);
      while Integer(bContinue) <> 0 do
      begin
        if LowerCase(aProcessEntry32.szExeFile) = LowerCase(ApplicationName) then result := aProcessEntry32.th32ProcessID;
        bContinue := Process32Next(aSnapshotHandle, aProcessEntry32);
      end;
      CloseHandle(aSnapshotHandle);
    end;
    function GetHandleFromProcID(aProcID : Cardinal) : Cardinal;
       function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
       begin
         TList(lParam).Add(Pointer(hWnd));
         Result := True;
       end;
    var
      List: TList;
      ProcessId: DWORD;
      I: Integer;
    begin
      Result := 0;
      List := TList.Create;
      try
        if EnumWindows(@EnumWindowsProc, Longint(List)) then
        begin
          for I := 0 to List.Count - 1 do
          begin
            GetWindowThreadProcessId(Longint(List.Items[I]), ProcessId);
            if aProcID = ProcessId then
            begin
              Result := Longint(List.Items[I]);
              Break;
            end;
          end;
        end;
      finally
        List.Free;
      end;
    end;
  begin
    result := GetHandleFromProcID(GetAppProcID(ApplicationName));
  end;
begin
  MyHandle := GetWindowByAppName(MyEXE);
  if (MyHandle <> 0 ) then Result := true
                      else Result := false;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sprint
Sprint

Registriert seit: 18. Aug 2004
Ort: Edewecht
712 Beiträge
 
Delphi 5 Professional
 
#9

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 11. Jan 2005, 01:21
Zitat von PremiumPils:
PostMessage(MyHandle, WM_CLOSE, 0, 0);
Laß dir doch in einer MessageBox das Fensterhandle und den Titel anzeigen. Dann kannst du die Werte ja mal mit Spy++, WinSpy oder X-Spy vergleichen. Vielleicht hast du ein Fenster der Anwendung, aber nicht das richtige.

Zitat von PremiumPils:
if LowerCase(aProcessEntry32.szExeFile) = LowerCase(ApplicationName) then result := aProcessEntry32.th32ProcessID;
Unter Windows 2000/XP/2003 steht dort nur der Dateiname drin. Unter Windows 9x steht in szExeFile der vollständige Dateiname drin.

Windows 2k/XP/2k3: NOTEPAD.EXE

Windowx 9x: C:\WINDOWS\NOTEPAD.EXE
Ciao, Sprint.

"I don't know what I am doing, but I am sure I am having fun!"
  Mit Zitat antworten Zitat
PremiumPils

Registriert seit: 26. Sep 2004
21 Beiträge
 
Delphi 7 Personal
 
#10

Re: Ferngesteuertes Schließen einer Anwendung

  Alt 12. Jan 2005, 19:26
Hallo, vielen Dank für Deine Hilfe. Ich hab das Problem nun eingrenzen und zu guter letzt auch lösen können. Es lag mehr oder weniger mit dem zu beendenden Programm zusammen, welches mal nur als Prozess in der Tray, mal minimiert in der Taskleiste und mal als Fenster da ist.. und mal überall. Toi toi toi... es geht nun.

Ganz nebenbei hab ich noch einen "Ungültiges Fensterhandle: 1400" und ein "Fehler beim Erstellen des Fenster-Gerätekontexts."-Fehler behoben.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz