MainWindowHandle richtig ermitteln und speichern...

  • VB.NET
  • .NET (FX) 4.0

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von DTF.

    MainWindowHandle richtig ermitteln und speichern...

    Moin! :)
    Ich möchte einen beliebigen Prozess starten z.B den „VLC-Player“.
    Wenn ich auf den Button1 klicke, wird dieser Prozess aufgerufen und gleich im Anschluss speichere ich den MainWindowHandle in eine List(Of String) Variable.

    Das Problem an der Sache ist!
    Ohne den Sleep(1000) hat der vlcProcess.MainWindowHandle einen 0 Wert.
    Wenn ich diese Sleep Methode verwende, dann habe ich den richtigen Wert.
    Ich bin der Meinung, dass passiert dadurch, weil das Programm zu schnell gestartet wird.
    Und es deshalb keinen Wert auslesen kann.

    Nun Meine Frage an euch:
    Kann ich diesen Code so anpassen, dass kein Sleep mehr benötigt wird?
    Weil ich vermute, dass eine ältere CPU vielleicht mehr als 1 Sekunde braucht.
    Und deshalb das Programm nicht fehlerfrei ausgeführt wird.
    Außerdem wäre es ohne, dass Sleep um einiges besser.
    Ich hoffe ich könnte mein Problem gut beschreiben, und freue mich auf eure Hilfe.

    Ich wünsche mir eine andere Lösung ohne das Sleep. ?(
    BIG THX

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form2
    3. Dim meineliste1 As New List(Of String)
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim vlcProcess As Process
    6. vlcProcess = New Process()
    7. vlcProcess.StartInfo.FileName = Me.txtVLCPlayerPfad.Text
    8. vlcProcess.StartInfo.Arguments = Me.txtMP3Pfad.Text
    9. vlcProcess.EnableRaisingEvents = True
    10. vlcProcess.Start()
    11. Application.DoEvents()
    12. 'System.Threading.Thread.Sleep(1000)
    13. ' Ohne Sleep hat die Variable einen 0 Wert!
    14. meineliste1.Add(vlcProcess.MainWindowHandle.ToString)
    15. ' Ausgabe...
    16. MsgBox(meineliste1(0))
    17. End Sub
    18. End Class
    Visual Basic.NET 8o
    MS-SQL
    8o
    @Cheffboss Verwende nach dem Start die Methode Process.WaitForInputIdle(), bis derr Prozess läuft.
    learn.microsoft.com/de-de/dotn…forinputidle?view=net-7.0

    Cheffboss schrieb:

    im Anschluss speichere ich den MainWindowHandle in eine List(Of String) Variable.
    1030 Posts im Forum???
    Machst Du Option Strict On :!: .
    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!
    Könnte sogar Option Strict On sein, siehe Zeile#17: .ToString. Ist zwar hanebüchen, das nicht mit dem Datentyp zu speichern, der zum Handle gehört, aber sei's drum.
    Aber MsgBox ist mal wieder VB6 :/
    Gut, Zeile#1 spricht ja auch für Option Strict On:rolleyes:
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    VaporiZed schrieb:

    Gut, Zeile#1 spricht ja auch für Option Strict On
    Überredet. ;)
    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!

    Rainman schrieb:

    vlcProcess.WaitForInputIdle()
    Hatten wir bereits in Post #2 in der ersten Zeile. ;)
    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!
    @an alle
    Vielen Dank, für eure Antwort.
    Ich habe herausgefunden, dass nicht jeder Prozess WaitForInputIdle unterstützt.
    Zum Beispiel der VLC-Player zeigt immer noch den 0 Wert an.
    Aber mit IrfanView wird der Wert richtig ausgelesen.
    Deshalb bin ich auf die Idee gekommen, eine Schleife zu verwenden.
    So bekomme ich auch bei schwierigeren Prozesse wie beim VLC-Player die richtige MainWindowHandle heraus.
    Ich verwende eine Do Loop Schleife.
    Und prüfe ob das Handle bereits einen anderen Wert hat als 0.
    Sobald dieses den richtigen Wert bekommen hat, verlasse ich die Do Loop Schleife.
    Zur Sicherheit! Um eine endlos Schleife zu vermeide.
    Warte ich 10 Sekunden und danach erst verlasse ich diese Schleife.
    Ich habe diesen Code getestet und er funktioniert soweit ganz gut.
    Jedenfalls habe ich es nun, ohne die lästige Sleep Methode hinbekommen.

    Ich habe nun die Lösung hier unten geschrieben und hoffe ich könnte jemanden auch mit meiner Lösung helfen.
    BIG THX

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Dim meineMainWindowHandle1 As IntPtr
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim vlcProcess As New Process
    6. vlcProcess.StartInfo.FileName = Me.txtVLCPlayerPfad.Text
    7. vlcProcess.StartInfo.Arguments = Me.txtMP3Pfad.Text
    8. vlcProcess.EnableRaisingEvents = True
    9. vlcProcess.Start()
    10. ' Warte mit einer Timeout-Zeitspanne von 10 Sekunden
    11. Dim timeout As TimeSpan = TimeSpan.FromSeconds(10)
    12. Dim startTime As DateTime = DateTime.Now
    13. Do
    14. ' Überprüfe, ob das Handle bereits verfügbar ist.
    15. If vlcProcess.MainWindowHandle <> CType(0, IntPtr) Then Exit Do
    16. ' Überprüfe, ob die Timeout-Zeitspanne erreicht wurde.
    17. If DateTime.Now - startTime >= timeout Then Exit Do
    18. Application.DoEvents()
    19. Loop
    20. meineMainWindowHandle1 = vlcProcess.MainWindowHandle
    21. ' Ausgabe...
    22. MsgBox(meineMainWindowHandle1.ToString)
    23. End Sub
    24. End Class
    Visual Basic.NET 8o
    MS-SQL
    8o

    Cheffboss schrieb:

    Warte ich 10 Sekunden und danach erst verlasse ich diese Schleife.
    Sieh Dir mal die Überladungen von Process.WaitForInputIdle(...) an: learn.microsoft.com/de-de/dotn…forinputidle?view=net-7.0
    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
    Ich habe das mit der Überladungen von Process.WaitForInputIdle auch versucht.
    Der vlcProcess.MainWindowHandle bleibt bei 0.
    Ich verwende Windows 11 Pro und den VLC-Player v3.0.18.

    Mit anderen Prozessen, geht das wunderbar!
    Aber leider nicht mit dem VLC-Player.

    VB.NET-Quellcode

    1. Dim zahl As Integer = 5000
    2. vlcProcess.WaitForInputIdle(zahl)


    Meinst du meine Lösung mit der Do Loop Schleife ist gut?
    Oder fällt dir ein besserer Weg ein.
    Freue mich auf jede Hilfe.
    Visual Basic.NET 8o
    MS-SQL
    8o

    Cheffboss schrieb:

    Freue mich auf jede Hilfe.

    Ein wenig kürzer:

    VB.NET-Quellcode

    1. vlcProcess.Start()
    2. Dim i As Long = Now.Ticks
    3. While vlcProcess.MainWindowHandle = IntPtr.Zero AndAlso Now.Ticks - i < 100000000 'bis zu 10 sekunden warten, solange das Handle 0 ist.
    4. End While
    5. MessageBox.Show($"Handle found after {Now.Ticks - i} ticks")

    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D