11/09/14 9:49
GN
Salve a tutti, ho questo problema in un'applicazione .NET. Ho bisogno di catturare l'output di un processo, sia ciò che viene scritto sullo standard output che sullo standard error; per ora, in particolare, sono interessato all'output del compilatore java (javac.exe, che in realtà scrive tutto su stderr, ma vorrei una soluzione "pulita" in modo che in futuro possa riutilizzare il codice per altri comandi che mandano alcuni messaggi di output su stdout e altri su stderr). In altre parole, ho bisogno di leggere in tempo reale stdout e stderr man mano che vengono scritti dal processo e nell'ordine giusto (ovvero non prima tutto stdout e poi tutto stderr o viceversa), esattamente come vengono mostrati quando il processo viene lanciato da terminale.
Detto questo, il codice che sono riuscito a scrivere è questo.
Come potete vedere la soluzione che mi è venuta in mente è di lanciare contemporaneamente due thread separati, uno per stdout e uno per stderr.
Inizialmente sembrava funzionare tutto, ma poi mi sono accorto di un comportamento strano: a volte certe righe di output non vengono lette, mente altre volte si (lanciando lo stesso identico comando con gli stessi parametri), in maniera apparentemente casuale.
Qualcuno saprebbe aiutarmi? Inoltre, secondo voi la soluzione dei due thread vi sembra una buona idea o ci sono alternative migliori? Grazie in anticipo a chiunque risponderà
PS: se qualcuno fosse interessato a vedere l'intero file di codice lo trovate qui: sourceforge.net/p/universalide/java-addon-code/ci/master/tree/Java%20for%20UniversalIDE/…
Detto questo, il codice che sono riuscito a scrivere è questo.
Delegate Sub onOutputDelegate(ByVal output As String, ByVal isError As Boolean) 'funzione che verrà chiamata ogni volta che il processo scrive qualcosa in uno dei due flussi di output Private Sub runCommand(ByVal cmd As String, ByVal onOutput As onOutputDelegate, Optional ByVal cwd As String = "") Dim p As New Process() p.StartInfo.FileName = cmd p.StartInfo.UseShellExecute = False p.StartInfo.CreateNoWindow = True p.StartInfo.RedirectStandardOutput = True p.StartInfo.RedirectStandardError = True If cwd <> "" Then p.StartInfo.WorkingDirectory = cwd p.Start() Dim thOut As New Thread(Sub() While Not p.HasExited onOutput(p.StandardOutput.ReadLine(), False) End While End Sub) Dim thErr As New Thread(Sub() While Not p.HasExited onOutput(p.StandardError.ReadLine(), True) End While End Sub) thOut.Start() thErr.Start() p.WaitForExit() End Sub
Come potete vedere la soluzione che mi è venuta in mente è di lanciare contemporaneamente due thread separati, uno per stdout e uno per stderr.
Inizialmente sembrava funzionare tutto, ma poi mi sono accorto di un comportamento strano: a volte certe righe di output non vengono lette, mente altre volte si (lanciando lo stesso identico comando con gli stessi parametri), in maniera apparentemente casuale.
Qualcuno saprebbe aiutarmi? Inoltre, secondo voi la soluzione dei due thread vi sembra una buona idea o ci sono alternative migliori? Grazie in anticipo a chiunque risponderà
PS: se qualcuno fosse interessato a vedere l'intero file di codice lo trovate qui: sourceforge.net/p/universalide/java-addon-code/ci/master/tree/Java%20for%20UniversalIDE/…
Ultima modifica effettuata da GN 11/09/14 9:51
aaa