How can I call a Perl script in a C # application?

I want to capture the output of a Perl program and display the output (a line on the screen) in a text box in C # Windows Form.

Here is my main C # code:

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:

 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{abcdefghijklmnopqrs }; 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: the output is displayed only in the text box until Perl finishes.

This is more interesting when I discovered that if I do the same with the console application (C #), everything will be fine.

Here is the code for the 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 is happening with my form application, but still can't find the hints. Another thing is that I cannot get a warning with a windows form application.

+6
c # perl
source share
2 answers

You will need to use multiple threads so that it does not overload your user interface. I have a fairly large utility class that runs processes in its thread and channels for delegated events.

Sorry, I will give an example, but in fact I am in a huge hurry. But another thing you'll want to observe with Perl scripts is that they do not automatically clear the output. You need to put:

 local $| = 1; 

At the top of your script that you run so that it is automatically erased.

+7
source share

First you need 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 to btnRun_Click

 proc.WaitForExit(); 
+2
source share

All Articles