Process beenden nachdem bestimmter string ausgelesen wurde

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Process beenden nachdem bestimmter string ausgelesen wurde

    Moin zusammen,

    ich habe folgendes:

    VB.NET-Quellcode

    1. ​Using p As New Process
    2. AddHandler p.OutputDataReceived, AddressOf Me.Process_OutputDataReceived
    3. ' Process definieren
    4. With p.StartInfo
    5. .FileName = "cmd"
    6. .CreateNoWindow = True
    7. .UseShellExecute = False
    8. .RedirectStandardInput = True
    9. .RedirectStandardOutput = True
    10. End With
    11. ' Process starten
    12. p.Start()
    13. ' Auszuführende Befehle
    14. Using sw As IO.StreamWriter = p.StandardInput
    15. sw.AutoFlush = True
    16. sw.WriteLine("cd files")
    17. sw.WriteLine("node app.js")
    18. End Using
    19. ' Ausgabe
    20. p.BeginOutputReadLine()
    21. End Using


    Desweiteren habe ich:

    VB.NET-Quellcode

    1. ​Private Delegate Sub LogDelegate(ByVal message As String, ByVal addDateTime As Boolean)
    2. Private Sub AppendLogLine(ByVal message As String, Optional ByVal addDateTime As Boolean = False)
    3. If addDateTime Then message = message
    4. With RichTextBox1
    5. If .InvokeRequired Then
    6. .Invoke(New LogDelegate(AddressOf Me.AppendLogLine), message, addDateTime)
    7. Else
    8. .AppendText(message & vbNewLine)
    9. If message.IndexOf("error: Login authentication failed") >= 0 Then
    10. Button2.Text = "Start"
    11. RichTextBox1.Clear()
    12. RichTextBox1.Text = "Login authentication failed!"
    13. 'Makierte Stelle - Process beenden
    14. Else
    15. RichTextBox1.SelectionStart = RichTextBox1.Text.Length
    16. RichTextBox1.ScrollToCaret()
    17. End If
    18. End If
    19. End With
    20. End Sub
    21. Private Sub Process_OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
    22. Me.AppendLogLine(e.Data, True)
    23. End Sub


    Jetzt möchte ich an der "Makierten stelle" den Process den ich mit "p.Start()" geöffnet habe, beenden.
    Wie mach ich das, ohne das er noch mal versucht "If message.IndexOf("error: Login authentication failed") >= 0 Then" zu prüfen,
    da er ja sonst ein Fehler auswirft
    System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

    "message" war "Nothing".


    Lg
    @PlatinSecurity Erstell nicht den Prozess in einem Using, sondern pack die Process-Variable WithEvents in die Klasse.
    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!
    Hey, danke für deine Antwort. Hab ich mal so gemacht, allerdings bekomme ich den Process einfach nicht geschlossen.
    Ob ich jetzt einfach

    Quellcode

    1. p.Close()
    mache oder es mit

    Quellcode

    1. Process.GetProcessesByName("cmd")(0).Kill()
    2. Process.GetProcessesByName("cmd")(0).CloseMainWindow()

    Ergibt alles nicht das, was ich gerne möchte.

    Er erkennt ja einmal "message.IndexOf("error: Login authentication failed") >= 0"
    Und dort hab ich halt das mit dem .Kill() oder .CloseMainWindow() beigefügt.
    Dennoch dauert es kurz und er prüft das noch mal und dann kommt wie oben schon erwähnt dieser eine Fehler.

    Vollzitat entfernt. ~Thunderbolt

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

    Nach meiner Erinnerung ist es so, dass cmd einen unabhängigen Prozess startet, der nicht mehr unter p erreichbar ist.
    Warum startest du den Inhalt deiner cmd nicht ohne Shell.

    ​cd files kannst du über StartInfo.WorkingDirectory abfedern und den node-Befehl kannst du über StartInfo.Filename und StartInfo.Arguments mitgeben.
    docs.microsoft.com/en-us/dotne…o?view=netframework-4.7.2

    Wenn du unbedingt über die cmd arbeiten willst, solltest du der cmd.exe zumindest das Argument /c mitgeben.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Danke für deine Antwort.
    Also ich mach das jetzt auch noch mal komplett anders als am Anfang gewollt.
    Vorher wollte ich ja ein CMD Fenster das mit NoWindow ausgelesen wird und in eine RichTextBox geschrieben wird.

    Jetzt mach ich das so, dass sich das CMD Fenster doch öffnet und man dort sieht was passiert.
    Das ganze mache ich im Code so:

    VB.NET-Quellcode

    1. Dim p As New Process
    2. p.StartInfo.Arguments = "/D /S /C cd files && node app.js"
    3. p.StartInfo.FileName = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "cmd.exe")
    4. '32 Bit OS: p.StartInfo.FileName = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe")
    5. If Button2.Text = "Stop" Then
    6. Button2.Text = "Start"
    7. Try
    8. Process.GetProcessesByName("cmd.exe")(0).Kill()
    9. Catch ex As Exception
    10. 'weiter...
    11. End Try
    12. Else
    13. If My.Settings.user = "" Or My.Settings.pw = "" Or My.Settings.soso = "" Then
    14. MsgBox("Please enter all data under Settings.", MsgBoxStyle.Critical, "Error - MOSB1")
    15. Else
    16. If Button1.Text = "Save" Then
    17. MsgBox("Please save all settings.", MsgBoxStyle.Critical, "Error - MOSB2")
    18. Else
    19. Button2.Text = "Stop"
    20. p.Start()
    21. End If
    22. End If
    23. End If


    heißt also, wenn ich auf Start drücke wird der Button zu Stop und der Process wird ausgeführt.
    Wenn ich dann auf Stop drücke soll jetzt der Button auf Start wieder umgewandelt werden und der Process gekillt werden.
    Button ändert sich auch aber der Process wird nicht beendet. Liegt vilt. daran, wie du schon sagtest das er nicht mehr unter Process zu finden ist ?!

    Habe da nämlich unter TaskManager das hier:


    EDIT: Alles klar... Gehirn lässt grüßen. Jetzt muss ich einfach:

    Quellcode

    1. Process.GetProcessesByName("node")(0).Kill()

    machen und der Process wird komplett zerstört und das Fenster somit geschlossen.

    Funktioniert somit alles. (bis jetzt xD)

    EDIT2: Kurze Frage noch nebenbei... Ist es möglich das CMD Fenster was sich da öffnet beim drücken auf den Button auch irgendwie nicht in der Taskleiste unten wo Start und so ist an zu zeigen? ... Wenn ja, wie wäre das machbar?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „PlatinSecurity“ ()

    @PlatinSecurity Warum zitierst Du den ganzen Post über dem Deinen? Das wird hier nicht gern gesehen.
    Wenn Du das Handle zum Consolefenster hast, kannst Du es auch aus der Taskbar ausblenden.
    Gugst Du hier: Angehängte Console kann nicht direkt geschlossen werden.

    @PlatinSecurity Ist Dein Problem nun gelöst?

    Beiträge zusammengefügt. Durch Löschung eines anderen Beitrags ist hier ein Doppelpost entstanden. ~Thunderbolt
    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!

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