2009-03-16 15 views
6

Desidero acquisire l'output di un programma Perl e visualizzare i dati di output (stringa sullo schermo) in una casella di testo in C# Windows Form.Come si chiama lo script Perl nell'applicazione C#?

Qui è il mio principale codice C#:

public partial class frmMain : Form 
{ 
    private Process myProcess = null; 
    public frmMain() 
    { 
     InitializeComponent();    
    } 

    public delegate void UpdateUIDelegate(string data); 
    private void btnRun_Click(object sender, EventArgs e) 
    { 
     myProcess = new Process(); 
     ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("perl.exe"); 
     myProcessStartInfo.Arguments = "test.pl"; 
     myProcessStartInfo.UseShellExecute = false; 
     myProcessStartInfo.RedirectStandardOutput = true; 
     myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     myProcessStartInfo.CreateNoWindow = true; 
     myProcess.StartInfo = myProcessStartInfo; 
     myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived); 
     myProcess.Start(); 
     myProcess.BeginOutputReadLine(); 
    } 

    void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     if (txtOutput.InvokeRequired) 
     { 
      UpdateUIDelegate updateDelegate = new UpdateUIDelegate(UpdateUI);     
      this.Invoke(updateDelegate, e.Data); 
     }    
    } 

    void UpdateUI(string data) 
    { 
     txtOutput.Text += data + "\r\n"; 
    } 
} 

e il codice per test.pl:

my @a = qw{1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19}; 
my @b = qw{a b c d e f g h i j k l m n o p q r s }; 
print 'start' . "\n"; 
while (my ($item1, $item2) = (splice (@a, 0, 1), splice (@b, 0, 1))) { 
    print 'Item 1: ' . $item1 . "\n"; 
    print 'Item 2: ' . $item2 . "\n"; 
    warn 'Finish one item' . "\n"; 
    sleep(1); 
} 

Ho un problema è che i dati di uscita viene visualizzato solo sulla casella di testo fino a quando il Perl ha finito.

è più interessante quando ho scoperto che, se io faccio la stessa cosa con un'applicazione console (C#) tutto sembra a posto.

Ecco il codice per l'applicazione di console:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Process myProcess = new Process(); 
     ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("perl.exe"); 
     myProcessStartInfo.Arguments = "test.pl"; 
     myProcessStartInfo.UseShellExecute = false; 
     myProcessStartInfo.RedirectStandardOutput = true; 
     myProcess.StartInfo = myProcessStartInfo; 

     myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);          
     myProcess.Start();    
     myProcess.BeginOutputReadLine();    
     Console.Read(); 
    } 

    static void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     Console.WriteLine(e.Data); 
    } 
} 

Sto cercando di capire cosa succede con la mia domanda forma, ma ancora non trovare alcun indizio. Un'altra cosa è che non riesco a ottenere il messaggio di avviso con l'applicazione di Windows Form.

+0

Ciao! Minh, sto usando il codice sopra per eseguire il file locale perl e ottenere l'output runtime nella casella di testo come previsto, ma quando eseguo il file bat della macchina remota dalla macchina locale. Questo file batch viene triggerato nella macchina remota ma l'output non viene visualizzato nella casella di testo. sto modificando solo queste 2 linee dall'alto codice 'ProcessStartInfo myProcessStartInfo = new ProcessStartInfo (" psexec.exe "); myProcessStartInfo.Arguments = "\\\\ machinename -u Dominio \\ usr -p pass C: \\ run.bat"; ' pls help me out. – picnic4u

+0

Hai provato a eseguire il comando in Prompt dei comandi? se sì, ha prodotto ciò che ti aspetti? –

+0

sì, lo stesso comando 'psexec \\ machinename -u Dominio \ usr -p pass c: \ run.bat' sta funzionando dal prompt dei comandi e dando l'output come previsto nel prompt dei comandi. – picnic4u

risposta

7

Si sta andando ad avere bisogno di utilizzare più thread in modo da non interrupt tua UI. Ho una classe di utilità abbastanza grande che avvia processi sul proprio thread e pipe a eventi delegati.

Scusate, vorrei fare un esempio ma in realtà sono in una corsa enorme. Ma un'altra cosa che vorrete fare attenzione con l'uso degli script Perl è che non riescono a svuotare l'output piacevolmente. Devi inserire:

Nella parte superiore dello script che stai utilizzando in modo che si scarichi automaticamente.

+0

Grazie, funziona come per magia :) –

2

In primo luogo è necessario aggiornare il gestore di eventi

void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)  
    {   
     if (txtOutput.InvokeRequired)   
     {    
       UpdateUIDelegate updateDelegate = new UpdateUIDelegate 

       (UpdateUI);this.Invoke(updateDelegate, e.Data);   
      } 
      else UpdateUI(e.Data); 

    } 

e aggiungere questa riga nel vostro btnRun_Click

proc.WaitForExit(); 
+0

In primo luogo, chiamando proc.WaitFroExit(); fai in modo che il thread principale (Thread UI) attenda fino al termine del programma Perl. Non lo voglio Voglio che il programma sia più reattivo. In effetti, il programma perl verrà eseguito in diverse ore. –

Problemi correlati