Prozess auch nach Neustart eindeutig identifizieren
-
Hi,
ich starte aus einer Apllikation heraus ein weiteres Programm. Ich muss sobald die Applikation den Fokus erhält (geht nicht anders) überprüfen, ob das gestartete Programm noch aktiv ist.Eigentlich kein Problem: zum Starten des Programmes benutze ich CreateProcess und merke mir die ProcessId. Erhält die Applikation den Fokus, überprüfe ich mit OpenProcess gefolgt von GetExitCodeProcess, ob das Programm noch aktiv ist.
Das funktioniert auch alles. Jetzt will ich aber auch beim Neustart von Windows bzw. meiner Applikation überprüfen, ob ein vorher gestartetes Programm noch aktiv ist, oder ob es in der Zwischenzeit beendet wurde, wobei ich nicht unterscheiden kann, ob meine Applikation den Fokus erhalten hat oder neu gestartet wurde (nicht fragen
). Leider kommt es vor, dass die, für das von meiner Applikation gestartete Programm, vergebene ProcessId nach einem Windows-Neustart an einen anderen Task vergeben wurde. Somit "merkt" meine Applikation nicht, das das Programm bereits beendet wurde.Frage: wie kann ich zusätzlich das von meiner Applikation gestartete Programm identifizieren? Ich habe ProcessVersion versucht, aber die scheint immer gleich zu sein.

Hat jemand eine Idee? Kennt z.B. jemand ein Möglichkeit, den Programmnamen oder den Pfad zum Executable anhand der ProcessId zu ermitteln?
Ciao
CompiguruFür alle, die Code brauchen:

bool ProcessInMem(long ProcessId, long DbProcessVersion) { unsigned long ExitCode; HANDLE hProcess = NULL; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessId); if(hProcess != NULL) { GetExitCodeProcess(hProcess, &ExitCode); CloseHandle(hProcess); if(ExitCode == STILL_ACTIVE) { DWORD ProcessVersion = GetProcessVersion(ProcessId); if(DbProcessVersion == ProcessVersion) //Funktioniert nicht, weil ProcessVersion immer gleich? return true; } } return false; }
-
Vergiss die Prozessid. Behalte des Handle, dass Du durch ShellExecuteEx oder CreateProcess erhälst. Solange Du dieses nicht schließt, kannst Du auch damit abfragen (WaitForSingleObject) ob dieser Prozess noch läuft. Ein Handle wird nicht recycled, wenn einer es noch offen hält.
-
Martin Richter schrieb:
Vergiss die Prozessid. Behalte des Handle, dass Du durch ShellExecuteEx oder CreateProcess erhälst. Solange Du dieses nicht schließt, kannst Du auch damit abfragen (WaitForSingleObject) ob dieser Prozess noch läuft. Ein Handle wird nicht recycled, wenn einer es noch offen hält.
Öhm, leider ist der Handle nachdem windows bzw. die Applikation neu gestartet wurde nicht mehr gültig.
Außerdem soll nicht gewartet werden (WaitForSingleObject), bis das Programm beendet wird. Es soll ein Arbeiten in der aufrufenden Applikation möglich sein. 
-
Nach einem Windows Neustart ist deine gestartete Anwendung auch bestimmt nicht mehr da

(und WaitForSingleObject() kannst du auch für "bist du noch da?" Fragen verwenden - wenn du als Timeout 0 übergibst, kehrt es sofort zurück - entweder mit WAIT_OBJECT0 (Prozess bereits beendet) oder mit WAIT_TIMEOUT (Prozess läuft noch))
-
CStoll schrieb:
Nach einem Windows Neustart ist deine gestartete Anwendung auch bestimmt nicht mehr da

Das stimmt, aber leider "weiß" meine Applikation nicht, ob es seit dem letzten Aufruf einen Neustart von Windows gab. Daher geht die Applikation davon aus, dass evtl. noch gestartete Programme aktiv sind und will dies anhand der ProcessId überprüfen. Diese wurde jedoch evtl. bereits an einen anderen Task vergeben.
Daher meine Frage: kennt jemand eine Möglichkeit, den Programmnamen oder den Pfad zum Executable anhand der ProcessId zu ermitteln? Und warum ist die ProcessVersion immer gleich? Laut MSDN "The version number returned by this function is the version number stamped in the image header of the .EXE file the process is running." sollte diese von Programm zu Programm unterschiedlich sein, oder?
Ciao
Compiguru
-
Das stimmt, aber leider "weiß" meine Applikation nicht, ob es seit dem letzten Aufruf einen Neustart von Windows gab
Dann ändere das.
Und warum ist die ProcessVersion immer gleich? Laut MSDN "The version number returned by this function is the version number stamped in the image header of the .EXE file the process is running."
Lesen, verstehen.
Die Versionsnummer steht in der .EXE Datei drinnen, wieso sollte sich die ändern solange man die .EXE nicht ändert?
Und: du kannst davon ausgehen dass die für viele Programme gleich sein wird, ganz einfach weil viele dieses Feature nicht nutzen, und daher oft der Default-Wert drinnen steht.
-
hustbaer schrieb:
Das stimmt, aber leider "weiß" meine Applikation nicht, ob es seit dem letzten Aufruf einen Neustart von Windows gab
Dann ändere das.
Und warum ist die ProcessVersion immer gleich? Laut MSDN "The version number returned by this function is the version number stamped in the image header of the .EXE file the process is running."
Lesen, verstehen.
Die Versionsnummer steht in der .EXE Datei drinnen, wieso sollte sich die ändern solange man die .EXE nicht ändert?
Und: du kannst davon ausgehen dass die für viele Programme gleich sein wird, ganz einfach weil viele dieses Feature nicht nutzen, und daher oft der Default-Wert drinnen steht.Sehr nützliche Ratschläge.

Ändern kann ich es nicht - aus technischen Gründen.
Appropos Lesen, verstehen. Da ich mit der ProcessId erst das eine und dann evtl. ein anderes Programm zufassen habe, sollt die ProcessVersion sich doch zwischen 2 verschiedenen Programmen unterscheiden, oder? Die ProcessVersion wird durch den Linker gesetzt: haben alle Linker den gleichen Default-Wert?
-
Versuch 1:
Kann man nicht Windows irgendwie fragen, wann der Letzte Start des Systems war?
Sowas müsste doch irgendwo zu finden sein. Damit könnte man dann das Programm füttern und es würde merken, ob das system zwischenzeitlich neu gestartet wurde oder sonst eninen Ausfall hatte.Verusuch 2:
Wenn das System neustartet, startet dann nicht auch die Aplikation neu die alles Kontrollieren soll? Dann könnte man evtl. Datum und Uhrzeit vergleichen.
-
Also sehe ich das richtig - du willst ein anderes Programm starten und (nachdem du selber beendet und neu gestartet wurdest) wiederfinden? Da dürfte es schon schwierig werden, Daten über den Programm-Neustart zu retten.
(an die Experten: Werden noch offene Rest-Handles eigentlich freigegeben, wenn ich das Besitzer-Programm ohne ein CloseHandle beende? Und kann eine neue Instanz des Programms dann dieses Handle übernehmen und weiter verwenden?)Hast du das Programm eigentlich selber geschrieben, das du da kontrollieren willst? Wenn ja, könntest du es ja fragen, ob es noch da ist (es gibt verschiedene Lösungen, um ein mehrfaches Öffnen des Programms zu verhindern - die lassen sich sicher dafür anpassen).
@ProcessVersion:
In der MSDN steht auch:If the function succeeds, the return value is the version of the system on which the process expects to run.
-
Hm, ok ein paar mehr Details:

Stellt euch mein Programm als Menüpogramm vor. Mein Programm wird beim Start von Windows automatisch gestartet. Der Anwender kann mit meinem Programm div. nicht von mir geschriebene Programme - auch parallel - starten. Die Fremdprogramme kommunizieren per XML mit meinem Programm. Jedes Mal, wenn mein Programm den Fokus erhält, prüft es, ob ein zuvor gestartetes Fremdprogramm noch im Speicher ist. Falls nicht, wird eine XML-Datei geöffnet und die dort evtl. gespeicherten Daten in mein Programm (sprich: Datenbank) übernommen.
Ich wollte keine Extra-Wurst für den Neustart von Windows implementieren und hatte gehofft, dass es eine eindeutige Methode gibt, um ein Programm zu identifizieren, sofern nur die ProcessId bekannt ist. Da meine Anwendung auch den Pfad und Programmnamen kennt, hatte ich gehofft, diese Informationen könnten irgendwie anhand der ProcessId ermittelt werden. Geht wohl leider nicht

Ich werde also einfach davon ausgehen, dass alle von meinem Programm gestarteten Fremdprogramme vor dem Start meiner Anwendung beendet wurden. Ist eh sehr wahrscheinlich, da der Anwender keine Möglichkeit hat (außer Abmelden bzw. Neustart), meine Anwendung zu beenden, bevor nicht alle Fremdprogramme beendet wurden. Ich wollte eben alles über eine Routine abwickeln. Bin manchmal ein wenig stur.

Danke für die zahlreichen Beiträge und Ideen!

Ich wünsche allen schonmal frohe Weihnachten und einen gute Rutsch! :xmas1: :xmas1:
Ciao
CompiguruPS: Ich denke nicht, dass Handles offen bleiben, nachdem das öffnende Programm beendet wurde.