0

I have a c# service that needs to call a perl script. Right now I have the perl script on my desktop and just reference the complete path of the desktop. Is it possible to add the perl script to the c# project and have it build to the same directory as the .exe that is generated after building? That way the file can be referenced from the current path. Code is below. Also the perl script uses sensitive information that I don't want on the script, would the best way to do this be passing the sensitive information as a parameter through c#?

Thanks,

ProcessStartInfo perlStartInfo = new ProcessStartInfo(@"C:\strawberry\perl\bin\perl.exe"); perlStartInfo.RedirectStandardInput = true; perlStartInfo.UseShellExecute = false; perlStartInfo.CreateNoWindow = true; Process perl = new Process(); perl.StartInfo = perlStartInfo; perl.Start();

        byte[] byteArray = Encoding.ASCII.GetBytes(Properties.Resources.TransferChange);

        using (MemoryStream stream = new MemoryStream(byteArray))
        {

            stream.CopyTo(perl.StandardInput.BaseStream);

            // this will cause perl to execute the script
            perl.StandardInput.Close();
        }
        perl.Start();
        perl.WaitForExit();
        string output = perl.StandardOutput.ReadToEnd();

I added perl.Start(); to the code. I get all the way to perl.WaitForExit(); but it just hangs there. Any idea?

1
  • Add it to project and set to copy during build... Is it what you need? Commented Nov 24, 2013 at 23:57

1 Answer 1

1

If you want to never persist the .pl file to disk, you could start perl.exe and pipe the script in via STDIN from a resource stream. Add the perl file to your project, set build action to be "Resource" then use the below to start the process:

// set up processstartinfo 
perlStartInfo.RedirectStandardInput = true;
Process perl = new Process();
perl.StartInfo = perlStartInfo;
perl.Start();

using (var scriptStream = typeof(ThisClassType).Assembly.GetResourceStream(new Uri("thescript.pl")).Stream)
{
    scriptStream.CopyTo(perl.StandardInput.BaseStream);
    // this will cause perl to execute the script
    perl.StandardInput.Close();
}

perl.WaitForExit();
string output = perl.StandardOutput.ReadToEnd();
Sign up to request clarification or add additional context in comments.

6 Comments

scriptStream.CopyTo() expects a stream. perl.StandardInput is a streamwriter.
@user541597, fixed. You can access the basestream
that fixed that issue. Also I am creating a service and for some reason I don't have the Application object so instead I used this. Assembly.GetExecutingAssembly().GetManifestResourceStream("TransferChange.pl") would this accomplish the same thing? I also added my script to the resources instead of adding to project and setting it to resource.
@user541597, yes, that is fine. You can also use typeof(ATypeInMyAssembly).Assembly.GetManifestResourceStream("name") if you are going to be loaded by ASP.Net, which does not return for GetExecutingAssembly
I am gettting this error on string output = perl.StandardOutput.ReadToEnd(); "StandardOut has not been redirected or the process hasn't started yet."
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.