tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
22
ZUGRIFFE
2082
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Hi,
    ich versuche mit folgendem Sub ein programm zu starten

    Code vbnet:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
        Private Sub RunApp(ByVal Befehl As String, ByVal Parameter As String)
            Dim Run As Process = New Process
     
            Run.StartInfo.FileName = Befehl
            Run.StartInfo.Arguments = Parameter
            Run.StartInfo.UseShellExecute = False
            Run.StartInfo.RedirectStandardOutput = True
            Run.StartInfo.RedirectStandardError = True
            Run.StartInfo.RedirectStandardInput = True
            Run.StartInfo.CreateNoWindow = True
            Run.Start()
     
            TextBox1.Text += Run.StandardOutput.ReadToEnd() & vbCrLf
            TextBox1.Text += Run.StandardError.ReadToEnd() & vbCrLf
            TextBox1.SelectionStart = Len(TextBox1.Text)
            TextBox1.ScrollToCaret()
            TextBox1.Focus()
            Application.DoEvents()
            Run.WaitForExit()
        End Sub

    Jetzt würde ich es gerne hinbekommen, das dieses Programm in einem Extra Thread läuft.

    Ich weiß das man das mit Dim ExtraThread As New Thread(AddressOf RunApp)
    macht. Jetzt bekomm ich nur immer folgende Meldung:
    Zitat Zitat von Meldung
    Fehler bei der Überladungsauflösung, da keine zugreifbare "New" mit diesen Argumenten aufgerufen werden kann:
    'Public Sub New(start As System.Threading.ParameterizedThreadStart)': Die Signatur der Private Sub RunApp(Befehl As String, Parameter As String)-Methode ist mit dem Delegaten "Delegate Sub ParameterizedThreadStart(obj As Object)" nicht kompatibel.
    'Public Sub New(start As System.Threading.ThreadStart)': Die Signatur der Private Sub RunApp(Befehl As String, Parameter As String)-Methode ist mit dem Delegaten "Delegate Sub ThreadStart()" nicht kompatibel.
    Ich hab zwar raus gefunden, das der Fehler daran liegt, das das Sub mehr als einen Parameter hat, aber es muss doch eine Möglichkeit geben, das das programm trotzdem in einem Extra Thread startet oder?
     

  2. #2
    Masterclavat Masterclavat ist offline Mitglied Brokat
    Registriert seit
    Oct 2007
    Beiträge
    325
    Vielleicht hilft dir das.
     

  3. #3
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Hallo,

    ich denke, einen Thread brauchst du dafür nicht zu erzeugen.
    Schaue dir mal den Exited-Event der Process-Klasse an. Damit kannst du dich über die Beendigung des externen Programmes benachrichtigen lassen, ohne mit WaitForExit die aufrufende Methode zu blockieren.

    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  4. #4
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    @Masterclavat: Hat mir leider nicht so ganz geholfen, da in dem Beispiel mehrere Forms benutzt wurden, ich aber nur eine habe und auch nur eine Klasse.

    @MCoder: Ich wollte das Programm in einem Extra Thread laufen lassen, weil bei Programmen die eine Weile im Hintergrund laufen, gleich die ganze Form für die Zeit einfriert und das wollte ich damit verhindern.
     

  5. #5
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Zitat Zitat von Thau Beitrag anzeigen
    @MCoder: Ich wollte das Programm in einem Extra Thread laufen lassen, weil bei Programmen die eine Weile im Hintergrund laufen, gleich die ganze Form für die Zeit einfriert und das wollte ich damit verhindern.
    Genau das wird ja damit erreicht.

    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  6. #6
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Ich hab den Sub jetzt mal so gändert:
    Code vbnet:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
        Private Sub RunApp(ByVal Befehl As String, ByVal Parameter As String)
            Dim Run As Process = New Process
     
            Run.StartInfo.FileName = Befehl
            Run.StartInfo.Arguments = Parameter
            Run.StartInfo.UseShellExecute = False
            Run.StartInfo.RedirectStandardOutput = True
            Run.StartInfo.RedirectStandardError = True
            Run.StartInfo.RedirectStandardInput = True
            Run.StartInfo.CreateNoWindow = True
            Run.Start()
     
            TextBox1.Text += Run.StandardOutput.ReadToEnd() & vbCrLf
            TextBox1.Text += Run.StandardError.ReadToEnd() & vbCrLf
            TextBox1.SelectionStart = Len(TextBox1.Text)
            TextBox1.ScrollToCaret()
            TextBox1.Focus()
            Application.DoEvents()
            'Run.WaitForExit()
            If (Run.HasExited) Then
                MessageBox.Show("Finished!")
            End If
        End Sub

    Aber auch wenn ich das Run.WaitForExit() rausnehme oder nicht, das Programm friert trotzdem ein.
     

  7. #7
    Avatar von Nico Graichen
    Nico Graichen Nico Graichen ist offline aka gemballa
    tutorials.de Moderator
    Registriert seit
    Dec 2003
    Ort
    Pulheim (NRW)
    Beiträge
    3.898
    Blog-Einträge
    34
    Hi

    Debug doch mal und schau an welcher Stelle er "hängt".
    Ich geh davon aus, dass das StandardOutput.ReadToEnd() und/oder StandardError.ReadToEnd() der Fall ist, da diese synchron laufen:
    Zitat Zitat von MSDN
    Der umgeleitete StandardOutput-Stream kann synchron oder asynchron gelesen werden. Methoden wie Read, ReadLine und ReadToEnd führen synchrone Lesevorgänge im Ausgabestream des Prozesses aus. Diese synchronen Lesevorgänge werden erst beendet, wenn der zugeordnete Process Daten in den StandardOutput-Stream schreibt oder den Stream schließt.
    Entweder du fragst die Daten nach Beenden des Prozesses ab (siehe Exited-Event) oder du machst das über die asynchonen Methoden Begin- und EndRead.
     
    Grüße Nico
    ----------------------
    Xing
    ----------------------
    Zitat Zitat von Mark Twain (1835-1910)
    Es gibt drei Dinge, die eine Frau aus dem Nichts hervorzaubern kann: einen Hut, einen Salat und einen Ehekrach.
    Zitat Zitat von Mike Wilson - Biographie über Larry Ellison (CEO Oracle)
    The Difference Between God and Larry Ellison: God Doesn't Think He's Larry Ellison

  8. #8
    Avatar von Alexander Schuc
    Alexander Schuc Alexander Schuc ist offline admin | crazy-weasel
    tutorials.de Administrator
    Registriert seit
    Aug 2001
    Ort
    Österreich, Stmk, Graz
    Beiträge
    2.783
    Natürlich.

    Dein "ReadToEnd" blockiert.

    ReadToEnd liest alles, bis der Stream geschlossen ist und das passiert halt erst, wenn dein Programm beendet ist.

    Anstatt von Threads könntest einfach die asynchrone Lestemethode benutzen, um die Ausgaben des Programms aufzusammeln.

    Hier siehst wie es geht.

    WaitForExit darfst natürlich dennoch nicht verwenden. Das würde dein Programm auch einfrieren. Stattdessen abonniere einfach das Exited Event.

    lg,..
     
    With the first link the chain is forged. The first speech censored, the first thought forbidden, the first freedom denied, chains us all irrevocably.
    Aaron Satie

    Legends... are the spice of the universe, Mr. Data, because they have a way of sometimes coming true.
    Captain Jean-Luc Picard, Stardate ~41294.5

    Tutorials.de chattet. Hier gibts auch .net Support ^^
    Klickt auf chattet und nutzt den Webchat, oder verbindet euch zu irc.tutorials.de - Channel #Tutorials.de

    (moo)blog furred.net // SiteInfo für WP7 // Pastebin für WP7 // BlogEngine.net Extensions

  9. #9
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Danke für die Hilfe. Ich hab mir mit der msdn Seite folgendes gebaut:
    Code vbnet:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
        Private Shared OutputString As StringBuilder = Nothing
        Private Shared numOutputLines As Integer = 0
     
     
        Private Sub RunApp(ByVal Befehl As String, ByVal Parameter As String)
            Dim Run As Process = New Process
     
            Run.StartInfo.FileName = Befehl
            Run.StartInfo.Arguments = Parameter
            Run.StartInfo.UseShellExecute = False
            Run.StartInfo.CreateNoWindow = True
            Run.StartInfo.RedirectStandardOutput = True
            Run.StartInfo.RedirectStandardError = True
            Run.StartInfo.RedirectStandardInput = True
            OutputString = New StringBuilder
     
            AddHandler Run.OutputDataReceived, AddressOf OutputStringHandler
     
            Run.Start()
     
            Run.BeginOutputReadLine()
            Run.BeginErrorReadLine()
     
            'TextBox1.Text &= Run.StandardOutput.ReadToEnd() & vbCrLf
            'TextBox1.Text &= Run.StandardError.ReadToEnd() & vbCrLf
     
            TextBox1.Text = OutputString.ToString
     
            TextBox1.SelectionStart = Len(TextBox1.Text)
            TextBox1.ScrollToCaret()
            TextBox1.Focus()
            Application.DoEvents()
            'Run.WaitForExit()
            If (Run.HasExited) Then
                TextBox1.Text &= "finished"
            End If
        End Sub
     
        Private Shared Sub OutputStringHandler(ByVal sendingProcess As Object, _
       ByVal outLine As DataReceivedEventArgs)
     
            ' Collect the sort command output.
            If Not String.IsNullOrEmpty(outLine.Data) Then
                numOutputLines += 1
     
                ' Add the text to the collected output.
                OutputString.Append(Environment.NewLine + "[" _
                             + numOutputLines.ToString() + "] - " _
                             + outLine.Data)
            End If
        End Sub

    Aber ich bekomme trotzdem den Inhalt nicht und ich weiß auch nicht wofür das OutputStringHandler sein soll.
     

  10. #10
    Avatar von Alexander Schuc
    Alexander Schuc Alexander Schuc ist offline admin | crazy-weasel
    tutorials.de Administrator
    Registriert seit
    Aug 2001
    Ort
    Österreich, Stmk, Graz
    Beiträge
    2.783
    Diesen StringBuilder namens "OutputString" kannst bei dir weglassen, und im "OutputStringHandler" fügst du den Text einfach deiner TextBox an, dann sollts klappen.

    "OutputStringHandler" ist der EventHandler für das Event welches gefeuert wird, wenn neue Daten vom Programm verfügbar sind.
     
    With the first link the chain is forged. The first speech censored, the first thought forbidden, the first freedom denied, chains us all irrevocably.
    Aaron Satie

    Legends... are the spice of the universe, Mr. Data, because they have a way of sometimes coming true.
    Captain Jean-Luc Picard, Stardate ~41294.5

    Tutorials.de chattet. Hier gibts auch .net Support ^^
    Klickt auf chattet und nutzt den Webchat, oder verbindet euch zu irc.tutorials.de - Channel #Tutorials.de

    (moo)blog furred.net // SiteInfo für WP7 // Pastebin für WP7 // BlogEngine.net Extensions

  11. #11
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Ich hab das OutputStringHandler jetzt so geändert:
    Code vbnet:
    1
    2
    3
    
        Private Sub OutputStringHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
            TextBox1.Text &= outLine.ToString
        End Sub

    Aber jetzt bekomme ich:
    Zitat Zitat von Fehler
    Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement TextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
    Oder muss ich das anders machen?
     

  12. #12
    calvin65 calvin65 ist offline Mitglied Bronze
    Registriert seit
    Nov 2005
    Beiträge
    31
    Das ist jetzt ein anderer Thread, daher musst du den Zugriff auf das Formular und damit auch die Textbox per "Invoke" und Delegate durchführen.
     
    MfG Calvin

  13. #13
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Mit dem ganzen Threading und den Delegates komme ich leider überhaupt nicht klar und das ganze Funktioniert einfach alles nicht wie es soll. Jetzt kommt nichtmal mehr die Meldung "finished"....
     

  14. #14
    Avatar von Nico Graichen
    Nico Graichen Nico Graichen ist offline aka gemballa
    tutorials.de Moderator
    Registriert seit
    Dec 2003
    Ort
    Pulheim (NRW)
    Beiträge
    3.898
    Blog-Einträge
    34
    Die Meldung wird auch nicht kommen, solang der neue Prozess länger als ein paar Ticks läuft! Process.HasExited ist solange false, bis der Prozess beendet ist. Wenn du die Meldung haben willst: Exited-Event

    Bzgl. Invoke
    Hier ist mal ein Beispiel: http://msdn.microsoft.com/de-de/library/ms171728.aspx
    Geändert von Nico Graichen (08.07.09 um 20:31 Uhr) Grund: Hab was besseres gefunden
     
    Grüße Nico
    ----------------------
    Xing
    ----------------------
    Zitat Zitat von Mark Twain (1835-1910)
    Es gibt drei Dinge, die eine Frau aus dem Nichts hervorzaubern kann: einen Hut, einen Salat und einen Ehekrach.
    Zitat Zitat von Mike Wilson - Biographie über Larry Ellison (CEO Oracle)
    The Difference Between God and Larry Ellison: God Doesn't Think He's Larry Ellison

  15. #15
    Thau Thau ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    32
    Ich komme trotzdem mit dem ganzen nicht klar. Das einzigste was ich wollte, ist das mein Programm eine externe Datei mit Parametern ausführt und die Ausgabe in eine Textbox schreibt und dabei mein Programm nicht einfriert. Was mich irritiert ist halt das gesagt wurde, ich brauch keinen Extra Thread sondern kann die asynchrone Lestemethode benutzen, aber da kommt dann plötzlich auch wieder die Meldung das es in einem Extra Thread ausgeführt wird.... Ich versteh das alles irgendwie ga rnicht mehr... *verzweifel*
     

Ähnliche Themen

  1. Process.Start geht auf Server2003 nicht
    Von Horscht1 im Forum .NET Windows Forms
    Antworten: 1
    Letzter Beitrag: 27.01.10, 22:54
  2. Process.Start Variable definieren
    Von mäcjava im Forum Visual Basic 6.0
    Antworten: 9
    Letzter Beitrag: 17.09.09, 12:00
  3. [vb.net] Process.Start()-Problem mit Leerzeichen
    Von Andreas Dunstheimer im Forum .NET Café
    Antworten: 6
    Letzter Beitrag: 26.08.07, 12:55
  4. [VC++.NET] Mit Process::Start() auch steuern
    Von the incredible Leitman im Forum .NET Web und Kommunikation
    Antworten: 1
    Letzter Beitrag: 28.03.07, 15:09
  5. Process = Thread?
    Von kahuna im Forum .NET Archiv
    Antworten: 1
    Letzter Beitrag: 11.08.04, 19:21

Stichworte