Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call Perl script in C# application?

Tags:

c#

perl

I want to capture output of a Perl program and display output data (string on screen) in a text box on 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{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.

It's more interesting when I found that, If I do the same with a console application (C#) everything seems okay.

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.

like image 532
Minh Le Avatar asked Mar 16 '09 11:03

Minh Le


Video Answer


1 Answers

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.

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:

local $| = 1;

At the top of your script that you're running so it auto flushes.

like image 106
Game_Overture Avatar answered Sep 30 '22 18:09

Game_Overture