tags:

views:

279

answers:

3

Hi, just downloaded ActivePerl. I want to embed the perl interpreter in a C# application (or at least call the perl interpreter from C#). I need to be able to send send out data to Perl from C#, then receive the output back into C#.

I just installed ActivePerl, and added MS Script Control 1.0 as a reference. I found this code on the internet, but am having trouble getting it to work.

 MSScriptControl.ScriptControlClass Interpreter = new MSScriptControl.ScriptControlClass();
Interpreter.Language = @"ActivePerl";
string Program = @"reverse 'abcde'";
string Results = (string)Interpreter.Eval(Program);
return Results;

Originally, it had 'PerlScript' instead of 'ActivePerl', but neither work for me. I'm not entirely sure what Interpreter.Language expects. Does it require the path to the interpreter?

Solved... I'm not sure how, but when I changed it back to PerlScript it works now. Still, I would like to know if MSScript Control is using ActivePerl or another interpreter.

A: 

I am not sure about the script control but I have done a similar thing where I had to 'embed' spamassasin (which is a Perl program). I basically used the Process to do the job. Something along the lines of:

var proc = new Process
    {
        StartInfo =
        {
            FileName = "perl",
            WorkingDirectory = HttpRuntime.AppDomainAppPath,
            Arguments = " myscript.pl arg1 arg2",
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            RedirectStandardInput = true,
            UseShellExecute = false
        }
    };
proc.Start();
proc.StandardInput.BaseStream.Write... // feed STDIN
proc.StandardOutput.Read... // Read program output
var procStdErr = proc.StandardError.ReadToEnd(); // errors
proc.StandardError.Close();
proc.StandardOutput.Close();
proc.WaitForExit(3000);
int exitCode = proc.ExitCode;
proc.Close();

This obviously not just Perl specific and it has the process creation overhead, so if you are running your script too often probably you need to think of a different solution.

Maxwell Troy Milton King
The important thing about your "embedding" is that it's not embedding. :-P
hobbs
I see :-) well you can do that too with this approach. Involves a bit of Perl magic but nothing too hard. You can pass your script to perls stdin and eval there or use a temp dir, or embed your acrip as 'embeded resource' in your DLL etc. Etc. It's just that Perl has never been stable in any hosted environment but as its own process. Hopefuly Perl 6... I am not sure about script control environment someone might prove me wrong.
Maxwell Troy Milton King
A: 

@MaxWell

Hi, I get directory not found exception (Win32 Exception) when working directory is set. Please help.

sheeba
A: 

You can run an external program as Maxwell suggests, in which case the external program can be Perl or anything else. It might be easier to use temp files to send the input data and get the output, but that depends on how the external program expects to get its data.

The alternative, which is what I think you're looking for, is to use the PerlNET compiler that comes with ActiveState's Perl Dev Kit. It lets you add a class wrapper around the Perl code so you can expose it to C# just like any C# class. It's fairly simple to use; you add POD comments to your Perl code to specify the method names and signatures to expose, including type information, then you compile your Perl module into a DLL .NET assembly. Once that's done you can reference the assembly from any .NET program, construct an object from your Perl class, and call its methods.

DougWebb