Die "WaitForExit"-Methode resigniert

  • VB.NET
  • .NET (FX) 4.0

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Die "WaitForExit"-Methode resigniert

    Hallo,
    Die "WaitForExit"-Methode resigniert und wartet nicht auf Beendigung einer Portable-Anwendung.

    Ich möchte aus meinem Programm heraus eine andere Anwendung mit Hilfe der Klasse "System.Diagnostics.Process" wie Microsoft in "Prozesse starten überwachen und beenden mit VB .NET" geschrieben hat, starten und warten bis diese beendet wurde.

    Wie oben erwähnt wurde, die Klasse System.Diagnostics.Process stellt die entsprechenden Werkzeuge zur Verfügung.

    VB.NET-Quellcode

    1. Dim ExterneAnwendung As New System.Diagnostics.Process()
    2. ExterneAnwendung.StartInfo.FileName = "C:\Portprog\PortableFireFox.exe"
    3. ExterneAnwendung.Start()
    4. ExterneAnwendung.WaitForExit()


    Also die Methode WaitForExit des Process-Objekts sollte den ausführenden Thread meiner Anwendung so lange anhalten,bis die externe Anwendung beendet wurde. Das tut sie aber nicht bei Portable-Anwendungen, die mit hilfe der VMware ThinApp erstellt wurden.

    Obwohl ich den Prozess "PortableFireFox" in Task-Manager sehe ist die Eigenschaft HasExited immer True
    und der Prozess kann durch die Kill-Methode abgeschoßen oder über die Schaltfläche "Prozess beenden" der Prozessliste in Task-Manager aus dem Speicher geworfen werden.

    Hat jemand eine Idee? Wie kann ich erreichen, dass meine Anwendung solange untätig wartet bis der Anwender PortableFireFox.exe beendet. Vielleicht Timer????

    Würde mich über einen Tipp freuen. Vielen Dank!


    Vielen Dank für die zahlreichen Tipps
    Die Lösungswege die hier vorgeschlagen wurde, habe ich bereits ausprobiert.
    Das Exited Event wird sofort ausgelöst obwohl die Methode WaitForExit im Code steht.
    Die Methode WaitForExit funktioniert bei allen normalen ausführbaren Dateien (z.B Excel.exe, xxx.exe, yyy.exe) einwandfrei.
    Ich werde versuchen dieses Problem mit Timer zu lösen und wenn ich erfolg habe, werde ich das Ergebnis hier präsentieren.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „1978lazigo“ ()

    @Christoph1972 Jou.

    1978lazigo schrieb:

    Die "WaitForExit"-Methode resigniert und wartet nicht auf Beendigung einer Portable-Anwendung.
    Möglicherweise hast Du sie nur nicht richtig initialisiert.
    Probier mal dies aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim WithEvents ExterneAnwendung As System.Diagnostics.Process
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. ExterneAnwendung = New System.Diagnostics.Process()
    4. ExterneAnwendung.EnableRaisingEvents = True
    5. ExterneAnwendung.StartInfo.FileName = "Notepad.exe"
    6. ExterneAnwendung.Start()
    7. ExterneAnwendung.WaitForExit()
    8. End Sub
    9. Private Sub ExterneAnwendung_Exited(sender As Object, e As EventArgs) Handles ExterneAnwendung.Exited
    10. MessageBox.Show("Exit")
    11. End Sub

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @1978lazigo Wenns nicht klappt, dann einfach nachdem du den Prozess startest folgende Schleife einfügen:

    VB.NET-Quellcode

    1. Dim LoopStopper as Boolean = False
    2. Dim prozess As System.Diagnostics.Process
    3. Do
    4. Application.DoEvents()
    5. For Each prozess In System.Diagnostics.Process.GetProcesses()
    6. If prozess.ProcessName.contains("PortableFirefox.exe") = true then
    7. LoopStopper = False
    8. Else
    9. LoopStopper = True
    10. Next
    11. Loop Until LoopStopper = True


    (Achtung: CODE NICHT GETESTET)
    Wäre zumindest eine Möglichkeit

    v-go schrieb:

    VB.NET-Quellcode

    1. Application.DoEvents()
    What :?:
    Teste mein Snippet und zieh Deinen Post zurück.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany: Müsste da nicht noch ein AddHandler Objekt.Event, AdressOf Handler_Methode dazu?

    VB.NET-Quellcode

    1. Dim WithEvents ExterneAnwendung As System.Diagnostics.Process
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. ExterneAnwendung = New System.Diagnostics.Process()
    4. ExterneAnwendung.EnableRaisingEvents = True
    5. AddHandler ExterneAnwendung.Exited, AddressOf ExterneAnwendung_Exited
    6. ExterneAnwendung.StartInfo.FileName = "Notepad.exe"
    7. ExterneAnwendung.Start()
    8. ExterneAnwendung.WaitForExit()
    9. End Sub
    10. Private Sub ExterneAnwendung_Exited(sender As Object, e As EventArgs) Handles ExterneAnwendung.Exited
    11. MessageBox.Show("Exit")
    12. End Sub
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    RodFromGermany schrieb:

    so


    wie der TE es schon im ersten Post geschrieben hat.

    VB.NET-Quellcode

    1. Sub Malfunction()
    2. Dim p As New Process
    3. p.StartInfo.FileName = "cmd"
    4. p.Start()
    5. p.WaitForExit()
    6. MessageBox.Show("")
    7. End Sub


    Also es funktioniert, nur der Thread in dem der Process gestartet wurde friert ein, aber nicht wenn man verwendet das Exited Event nutzt.
    And i think to myself... what a wonderfuL World!

    RodFromGermany schrieb:

    v-go schrieb:

    VB.NET-Quellcode

    1. Application.DoEvents()
    What :?:
    Teste mein Snippet und zieh Deinen Post zurück.


    Nein, warum sollte ich dein Snippet testen? Normalerweise funktioniert das auch mit "WaitForExit",
    Mein Snippet sollte eine Möglichkeit sein, falls es beim TE aus irgendeinem unerfindlichen Grund nicht klappt.

    Ps: Application.DoEvents(): msdn.microsoft.com/de-de/library/bd65th41(v=vs.90).aspx

    v-go schrieb:

    Application.DoEvents()
    Ist kalter Kaffee!
    Wie gesagt, verwende das Event
    Das besagte Application.DoEvents() ist aus früheren Zeit, als es noch kein Async/Await gab. Dabei hat man halt weiterhin den Rechenintensiven Teil im GUI-Thread erledigen lassen => UI friert ein. Um das UI trotzdem noch responsiv zu halten, gab es das Application.DoEvents. Da es ja seit FW 4.5 besagtes Async/Await gibt, kann man sich das ganze auch sparen.
    Viel wichtiger ist aber folgendes: Der TE braucht weder das eine (Application.DoEvents()) noch das andere (Async/Await).
    Es geht lediglich darum, eine Benachrichtigung zu erhalten, wenn der Prozess beendet (Exited) => Verwende - wenn MSDN es schon anbietet - das Event!

    @v-go: Wieso weigerst du dich bitte so vehement dagegen, das Snipped zu testen? Meine Eltern haben mir beigebracht, dass ich alles zumindest mal probieren soll.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    Radinator schrieb:

    AddHandler
    Oder eben

    VB.NET-Quellcode

    1. Private Sub ExterneAnwendung_Exited(sender As Object, e As EventArgs) Handles ExterneAnwendung.Exited
    -----

    Eddy schrieb:

    funktioniert
    blockiert aber die Anwendung.

    v-go schrieb:

    Nein, warum
    um zu lernen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany: Ups...das kommt davon, wenn man sich längere Zeit mit C# beschäftigt und keine Handles-Klaseln mehr verwendet ;D Habs einfach übersehen
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator Nein, Nein, ich weigere mich keinesfalls vehement das Snippet zu testen. Events sind eine feine Sache und das gepostete Snippet von Rod funktioniert auch, das sehe ich bereits wenn ich das Snippet lese.

    1978lazigo schrieb:

    reibungslos
    Hast Du mal exakt meinen Code aus Post #3 ausprobiert?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ach Leute. Warum geht ihr nicht dem eigentlichen Problem auf den Grund? Der TE schreibt, dass er die Apps mit VMware ThinApp erstellt. Ohne Analyse einfach irgendeinen Code hinzurotzen, der nur vielleicht funktioniert, ist nicht hilfreich. Noch dazu wenn die "Lösung" aus haarsträubenden Konstrukten wie Polling in allen erdenklichen Formen besteht.

    Zugegeben, weit bin ich auch nicht gekommen, weil der ThinApp-Creator bei mir aus welchem Grund auch immer nicht läuft. Eine Beispieldatei (portable notepad oder so) wäre tatsächlich hilfreich. Aufgrund der beschriebenen Verhaltensweise nehme ich an (!), dass der überwachte Prozess einen weiteren Prozess erstellt und sich dann selbst beendet, während der Kindprozess weiter läuft. Eine saubere Lösung könnte daher die Überwachung des Systems auf neu erstellte Prozesse (z.B. per WMI-Event) sein, verbunden mit dem Vergleich, ob [neuer Prozess].ParentPID == [ThinApp-Prozess].PID. Endet der Elternprozess, muss der Kindprozess bereits laufen und man kann auf dessen Ende warten, ggf. mit erneuter Prüfung auf weitere Kindprozesse.

    Bei der Analyse hilft der Process Monitor von Sysinternals.

    Prozessmonitor mit WMI: weblogs.asp.net/whaggard/438006

    Andere Lösung: Lade dir das ThinApp SDK herunter und lies dessen Dokumentation. Ein ThinApp-Container bietet diverse Ereignisse, darunter das von dir benötigte OnLastProcessExit (siehe ThinAppAPI.pdf, Seite 22). Dieses Event erfordert allerdings eine unmanaged-DLL. Daneben gibt es WaitForProcess(id, timeout) - das müsste per p/Invoke auch aus .NET heraus gehen.
    Gruß
    hal2000

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hal2000“ ()

    hal2000 schrieb:

    Eine Beispieldatei (portable notepad oder so) wäre tatsächlich hilfreich


    Hallo hal2000,
    ich habe eine Datei (PortableNotepad++) ca. 11mb gross und würde gerne euch zur Verfügung stellen. Ich bin sehr neugierig und warte auf eine Lösung.

    Edit by hal2000: Vollzitat entfernt.
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hal2000“ ()