Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Fremdes Programm beenden - Handle anhand Filename ermitteln (https://www.delphipraxis.net/155242-fremdes-programm-beenden-handle-anhand-filename-ermitteln.html)

Ines 14. Okt 2010 13:07

Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Hallo DP'ler,

ich suche seit 2 Tagen hier im Forum nach der richtigen Lösung - und seh' wahrscheinlich den Wald vor lauter Bäumen nicht mehr!

Mit ShellExecuteEx kann der Nutzer sich Bilder, PDF- und HTML-Files eines Patienten anzeigen lassen. Funktioniert einwandfrei.

Wird nun der nächste Patient aufgerufen, dann möchte ich, daß alle Fenster, die mit ShellExecuteEx erstellt wurden, auch wieder geschlossen werden.

Mit ENumWindow (ich glaube der Code ist von Lucky) kann ich mir alle Fensterbezeichnungen in einer ListBox anzeigen lassen.

Mein Problem: Wie komme ich über diese Bezeichnung zur Prozess-ID (z.B. Adobe), damit ich dieses Programm beenden kann?

Vielen Dank für Eure Hilfe
Ines

DeddyH 14. Okt 2010 13:15

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Hast Du diesen Thread schon gelesen?

Sir Rufo 14. Okt 2010 13:23

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Wenn du doch diese startest, dann Merk dir diese in einer Liste und beende diese dann (siehe Link von DeddyH)

Denn nicht jedes Programm (z.B. Adobe Reader) wurde von dir gestartet, es sei denn das ist beabsichtigt.

Luckie 14. Okt 2010 13:30

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Die Liste liefert auch das Handle. damit kann man WM_LOSE an das Fenster senden.

DeddyH 14. Okt 2010 13:31

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Das mit WM_CLOSE (:mrgreen:) wurde auch im verlinkten Thread genannt.

Sir Rufo 14. Okt 2010 13:33

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Zitat:

Zitat von DeddyH (Beitrag 1055770)
Das mit WM_CLOSE (:mrgreen:) wurde auch im verlinkten Thread genannt.

Darum ja der explizite Hinweis auf WM_LOSE :mrgreen:

DeddyH 14. Okt 2010 13:35

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Zitat:

Zitat von Pappa ante portas
Mein Name ist Lose - ich kaufe hier ein.

Aber nun genug OT ;)

Ines 14. Okt 2010 14:41

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Hallo und Danke für Eure Hilfe!

Den Thread habe ich gelesen - habe aber Probleme, das richtige Handle zu ermitteln. Der Rückgabewert von ShellExecuteEx scheint nicht das Fensterhandle zu sein (oder ich bin zu dumm!).

Mein Problem habe ich jetzt folgendermaßen gelöst:
Ich habe in GetWindows eine Abfrage eingebaut, die nach dem nicht zu löschenden Dateinamen sucht. Wenn vorhanden, dann habe ich ja das Handle und kann das Fenster mit Sendmessage (hwnd, WM_Close, SC_Close) beenden.

Das dürfte dem Nutzer die größtmöglichste Freiheit geben - mal' schauen.

Viele liebe Grüße
Ines

DeddyH 14. Okt 2010 14:45

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Wie im verlinkten Thread bereits gesagt würde ich die Fenster durchgehen und die Prozesshandles vergleichen: http://www.delphipraxis.net/999827-post2.html

Bummi 14. Okt 2010 15:41

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

begin
  ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFO);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.lpVerb := nil;
  ShExecInfo.lpFile := PChar('NotePad.exe');
  ShExecInfo.lpDirectory := nil;
  ShExecInfo.nShow := SW_Show;
  if not ShellExecuteEx(@ShExecInfo) then Showmessage(IntToStr(GetLastError));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TerminateProcess(ShExecInfo.hProcess,0);
  CloseHandle(ShExecInfo.hProcess);

  ODER: su.
  SendMessage(FindMainWindow(7964),WM_Close,0,0);

end;

Delphi-Quellcode:
type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record ProcessID: DWORD; HWND: THandle; end;

function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
    var
      PID: DWORD;
    begin
      GetWindowThreadProcessID(Wnd, @PID);
      Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or (not IsWindowEnabled(WND));
      if not Result then EI.HWND := WND;
    end;

  function FindMainWindow(PID: DWORD): DWORD;
    var
      EI: TEnumInfo;
    begin
      EI.ProcessID := PID;
      EI.HWND := 0;
      EnumWindows(@EnumWindowsProc, Integer(@EI));
      Result := EI.HWND;
    end;

Ines 15. Okt 2010 07:01

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Guten Morgen!

Nochmals zu meinem Problem - das ich hoffentlich jetzt gelöst habe.

Der Arzt kann sich via FTP alle Files eines Patienten lokal auf seinen PC laden. Er hat dann die Möglichkeit, sich diese Files mit ShellExecuteEx anzeigen zu lassen - kann aber auch über z.B. Explorer und Doppelklick solch ein File öffnen.

Werden jetzt Files vom nächsten Patienten geladen - dann muß das lokale Verzeichnis zuerst geleert werden. Wird z.B. noch ein pdf-File vom vorherigen Patienten angezeigt, dann scheitern alle Löschbemühungen.

Da ich nicht weiß, ob mein Programm die Fenster mit ShellExecuteEx geöffnet hat oder der Arzt via Explorer usw. dies getan hat funktioniert die Abfrage in GetWindows nach der nicht zu löschenden Datei am besten. Außerdem will ich z.B. Adobe auch nicht komplett abschießen, da der Arzt eventuell eine Publikation über ein bestimmtes Krankheitsbild geöffnet hat und die Files mit diesen Ergebnissen vergleichen will.

Ich danke Euch allen für Eure Mühe und auch für die Codebeispiele, die mir sehr geholfen haben.

Viele Grüße aus Augsburg
Ines

OldGrumpy 15. Okt 2010 07:29

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Manchmal kann es auch wirklich sinnvoll sein, dem User nicht seinen Brei direkt in den Mund zu schaufeln sondern ihn auch mal kauen zu lassen. Mit anderen Worten: Wenn der User zum nächsten Patienten will und noch Dateien offen sind, soll der User die offenen Fenster gefälligst selber zumachen, also entsprechende Meldung raus und weiter gehts. Klar ist der Computer nicht die Kernkompetenz des Arztes, aber wenn das Programm erst gar keine Intelligenz beim User voraussetzen kann, wozu isses dann für Ärzte? :mrgreen: Hoffentlich ist der Bediener nicht Chirurg und vergisst auch öfter mal was im Patienten... :mrgreen:

Sir Rufo 15. Okt 2010 07:54

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Das hängt vom eigenen Anspruch und der eigenen Sichtweise ab.

Wenn es möglich wäre und in sich logisch schlüssig (und die Usability erhöht) warum nicht realisieren.

So Dialoge wie "Um Fortzufahren müssen Sie zwingend xyz.pdf schließen"
Ja ich will fortfahren (diese Absicht habe ich kundgetan) und der Rechner weiß wie man den Zustand herstellt, dass ich fortfahren kann, dann soll der das gefälligst auch machen.

Es ist eine Gratwanderung zwischen Unterstützung und Bevormundung.

Wichtigstes Kriterium ist aber als Kernfrage "Wie schaffe ich es, dass der Anwender in seinem Arbeitsfluss nicht gestört wird?"
Es geht niemals um ein paar Klicks, sondern dass der Anwender in dem Moment eine andere Aufmerksamkeit hat wo diese (vermeidbaren) Klicks selbigen aus dieser Aufmerksamkeit reißen und eine völlig andere aufzwingen.

Will ich mit meiner Software den User unterstützen oder (aus reiner Bequemlichkeit, Faulheit, Unwissenheit, Ignoranz) behindern. Da muss jetzt jeder selber entscheiden wo er da stehen möchte.

Ich habe meinen Anspruch definiert (manche halten mich für pingelig :mrgreen: ) und prüfe bei jeder Programmierung (die zum User rausgeht) ob ich meinem Anspruch noch gerecht werde.
Ergänzend sollte ich noch sagen, dass ich in der glücklichen Lage bin den Zeitrahmen für ein Projekt mitgestalten zu dürfen und die Mitwirkenden (am Zeitrahmen) lieber ein gutes als ein schnelles Release haben möchten.

Denn der Anspruch bleibt auf der Strecke wenn die Zeit zu knapp ist.

PS War das jetzt schon das Wort zum Sonntag? :mrgreen:

Ines 15. Okt 2010 08:30

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Hallo,

Zitat:

Zitat von OldGrumpy (Beitrag 1055890)
Manchmal kann es auch wirklich sinnvoll sein, dem User nicht seinen Brei direkt in den Mund zu schaufeln sondern ihn auch mal kauen zu lassen.

Ich will meine Ärzte hier wirklich nicht verwöhnen (so groß ist die Liebe zwischen uns wirklich nicht :wall:). Aber mit dem Löschen mache ich mir das Leben leichter, da ich aus mehreren Directories am Server alle Daten zusammensuchen muß. Verlange ich nun vom Nutzer, daß er selbständig ein Fenster schließt, dann wird mein Programmablauf nicht leichter bzw. übersichtlicher.:wink:

Ihr seht, damit unterstütze ich meine eigene "Faulheit". Außerdem wird der Arzt im Programm auf die "Gefahr" des Schließen eines Fensters hingewiesen.
Allerdings werden hier diese Hinweistexte prinzipiell ignoriert.

Zitat:

Zitat von OldGrumpy (Beitrag 1055890)
Hoffentlich ist der Bediener nicht Chirurg und vergisst auch öfter mal was im Patienten... :mrgreen:

Nein - aber vielleicht würden Chirurgen meine Arbeit mehr schätzen.

Liebe Grüße
Ines

alf27 6. Feb 2011 11:31

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Hi Ines,

Schau mal an

http://www.swissdelphicenter.ch/de/showcode.php?id=327

vorbei.

Gruss

Alf

Dezipaitor 6. Feb 2011 11:43

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Das hört sich aber nach dem hier an:
http://www.remkoweijnen.nl/blog/2011...ed-the-origin/

Ist eine viel bessere Lösung als Dateihandles einfach so freizugeben.

sx2008 6. Feb 2011 12:21

AW: Fremdes Programm beenden - Handle anhand Filename ermitteln
 
Zitat:

Zitat von Ines (Beitrag 1055886)
Werden jetzt Files vom nächsten Patienten geladen - dann muß das lokale Verzeichnis zuerst geleert werden.

Warum diese technisch unnötige Einschränkung?
Vielleicht möchte der Dottore die Dokumente zweier Krebspatienten vergleichen; wer weiss...
siehe Sir Rufo's:
Zitat:

Wichtigstes Kriterium ist aber als Kernfrage "Wie schaffe ich es, dass der Anwender in seinem Arbeitsfluss nicht gestört wird?"
Da es im lokalen Verzeichnis zu Kollisionen von Dateinamen kommen könnte, braucht man doch nur für jeden Patienten ein Unterverzeichnis (evtl. Name=Patientennr) anzulegen.
Und zum Programmende werden alle temporären Verzeichnisse aus Datenschutzgründen wieder gelöscht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:03 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