如何在 C# 应用程序中调用 Perl 脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/649993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I call Perl script in C# application?
提问by Minh Le
I want to capture output of a Perl program and display output data (string on screen) in a text box on C# Windows Form.
我想捕获 Perl 程序的输出并在 C# Windows 窗体的文本框中显示输出数据(屏幕上的字符串)。
Here is my main C# code:
这是我的主要 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";
}
}
and code for test.pl:
和 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);
}
I have a problem is that the output data is only displayed on text box until the Perl has finished.
我有一个问题是输出数据只显示在文本框中,直到 Perl 完成。
It's more interesting when I found that, If I do the same with a console application (C#) everything seems okay.
当我发现这一点时更有趣,如果我对控制台应用程序 (C#) 做同样的事情,一切似乎都可以。
Here's the code for console application:
这是控制台应用程序的代码:
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);
}
}
I'm trying to figure out what happens with my form application but still not find any clue. One more thing is that I can not get warn message with windows form application.
我试图弄清楚我的表单应用程序会发生什么,但仍然没有找到任何线索。还有一件事是我无法使用 Windows 窗体应用程序收到警告消息。
采纳答案by Game_Overture
You're going to need to use multiple threads so it doesn't interupt your UI. I have a fairly large utility class that launches processes on its own thread and pipes to delegated events.
您将需要使用多个线程,这样它就不会中断您的 UI。我有一个相当大的实用程序类,它在自己的线程和管道上启动进程到委托事件。
Sorry, I'd give an example but I'm actually in a huge rush. But one thing else you will want to watch out for with using Perl scripts is that they do not auto flush the output nicely. You need to put:
抱歉,我想举个例子,但实际上我很着急。但是,使用 Perl 脚本时您还需要注意的另一件事是它们不能很好地自动刷新输出。你需要把:
local $| = 1;
At the top of your script that you're running so it auto flushes.
在您正在运行的脚本的顶部,它会自动刷新。
回答by Ahmed Said
First you have to update the event handler
首先,您必须更新事件处理程序
void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (txtOutput.InvokeRequired)
{
UpdateUIDelegate updateDelegate = new UpdateUIDelegate
(UpdateUI);this.Invoke(updateDelegate, e.Data);
}
else UpdateUI(e.Data);
}
and add this line in your btnRun_Click
并在您的 btnRun_Click
proc.WaitForExit();