2009-03-16 22 views
6

Bir Perl programının çıktısını almak ve C# Windows Formunda bir metin kutusuna çıktı verilerini (ekran üzerindeki dize) görüntülemek istiyorum. Bir sorun çıktı verileri sadece Perl kadar metin kutusuna görüntülenen olmasıdır sahipC# uygulamasında Perl komut dosyasını nasıl ararım?

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); 
} 

: test.pl için

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"; 
    } 
} 

ve kod: Burada

benim ana C# kodu bitti.

Bunu bulduğumda daha ilginç, eğer bir konsol uygulamasıyla (C#) aynısını yaparsam her şey iyi görünüyor. Ben benim form uygulaması ile olur ama yine de herhangi bir ipucu bulamadık anlamaya çalışıyorum

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); 
    } 
} 

:

İşte konsol uygulaması için kod. Bir şey daha Windows form uygulaması ile mesaj alamıyorum.

+0

Merhaba! Minh, Yerel perl dosyası çalıştırmak ve beklendiği gibi metin kutusu içinde çalışma zamanı çıktısını almak için yukarıdaki kodu kullanıyorum ama yerel makineden uzak makine yarasa dosyası çalıştırırken. Bu toplu iş dosyası uzak makinede tetiklenir ancak çıktı metin kutusunda gösterilmiyor. Sadece bu 2 satırı yukarıdaki koddan değiştiriyorum 'ProcessStartInfo myProcessStartInfo = new ProcessStartInfo (" psexec.exe "); myProcessStartInfo.Arguments = "\\\\ machinename -u Etki Alanı \\ usr -p geçiş C: \\ run.bat"; pls bana yardım et. – picnic4u

+0

Komutunu Komut İstemi'nde çalıştırmayı denediniz mi? eğer evet, beklediğiniz şeyi çıktı mı? –

+0

evet, aynı komut 'psexec \\ machinename -u Etki Alanı \ usr -p geçiş c: \ run.bat' komut isteminden çalışıyor ve komut isteminde beklendiği gibi çıktı veriyor. – picnic4u

cevap

7

bu çizgiyi eklemek zorunda senin UI. Kendi iş parçacığı ve borularındaki süreçleri temsilci olaylara başlatan oldukça büyük bir yardımcı program sınıfım var.

Üzgünüm, bir örnek vereyim ama aslında büyük bir acelem var. Ama Perl betikleri kullanarak dikkat etmek isteyeceğiniz başka bir şey de çıktıyı otomatik olarak temizlememesidir. Koymanız gerekir:

local $| = 1; 

Çalıştığınız komut dosyasının üst kısmında otomatik olarak temizlenir.

+0

Teşekkür ederim, sihir gibi çalışıyor :) –

2

Önce olay işleyicisi

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

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

    } 

güncelleme ve Sen interupt vermez birden çok konuları kullanmaya gerek olup olmadığınız btnRun_Click

proc.WaitForExit(); 
+0

İlk önce proc.WaitFroExit() öğesini çağırma; Perl programı bitene kadar ana iş parçacığı (UI Thread) bekleyin. Bunu istemiyorum. Programın daha duyarlı olmasını istiyorum. Aslında, perl programı birkaç saat içinde çalışacaktır. –

İlgili konular