如何在C#应用程序中调用Perl脚本?

时间:2009-03-16 11:10:13

标签: c# perl

我想捕获Perl程序的输出并在C#Windows窗体的文本框中显示输出数据(屏幕上的字符串)。

这是我的主要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";
    }
}

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

我有一个问题是输出数据只显示在文本框上,直到Perl完成。

当我发现它时,更有趣的是,如果我对控制台应用程序(C#)做同样的事情,一切似乎都没问题。

以下是控制台应用程序的代码:

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

我正在试图弄清楚我的表单应用程序会发生什么,但仍然没有找到任何线索。 还有一件事是我无法通过Windows窗体应用程序获得警告消息。

2 个答案:

答案 0 :(得分:7)

您将需要使用多个线程,因此它不会中断您的UI。我有一个相当大的实用程序类,它在自己的线程和管道上启动进程到委托事件。

对不起,我举一个例子,但我实际上是在匆匆忙忙。但是,使用Perl脚本需要注意的另一件事是它们不能很好地自动刷新输出。你需要把:

local $| = 1;

在您运行的脚本顶部,它会自动刷新。

答案 1 :(得分:2)

首先,您必须更新事件处理程序

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

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

     }

并在btnRun_Click

中添加此行
proc.WaitForExit();