views:

675

answers:

2

In my website I want to virus-check any uploaded files before saving them into my database. So I save the file to the local directory then kick-off a command-line scanner process from inside my C# program. Here is the code I use:

  string pathToScannerProgram = Path.Combine(virusCheckFolder, "scan.exe");
  ProcessStartInfo startInfo = new ProcessStartInfo();
  startInfo.FileName = pathToScannerProgram;
  startInfo.Arguments = String.Format("\"{0}\" /FAM /DAM", fileToScanPath);
  startInfo.RedirectStandardOutput = true;
  startInfo.WindowStyle = ProcessWindowStyle.Hidden;
  startInfo.UseShellExecute = false;

  using (Process process = new Process())
  {
    process.StartInfo = startInfo;
    process.Start();
    string output = process.StandardOutput.ReadToEnd();
    string errorLevel = Environment.GetEnvironmentVariable("ERRORLEVEL");
    process.WaitForExit();
  }

My problem is that Environment.GetEnvironmentVariable("ERRORLEVEL") is always returning null. It should be returning a number. So how do I get the "ERRORLEVEL" set by the command line scanner in my C# program?

+3  A: 

As far as I know that is just the ExitCode of your Process. Use that.

And it would only be useful to check that after waiting for the process to end, btw.

Benjamin Podszun
Thank-you for such a prompt answer!
Colin
+1  A: 

You appear to have translated a batch script, which checks the ERRORLEVEL special variable in lieu or the more familiar to unix scripting exit code.

ERRORLEVEL is a special variable which corresponds to the ExitCode of a process.

What your code is attempting to do is to read an environment variable from it's own process as it was set by the child process.

In this case of batch scripts which appear to be doing this they are in fact relying on the the operating system's scripting environment to alter this special variable for you when the laucnhed process exits. This is problematic when trying to replicate a similar functionality within a fuller featured programming environment (for why this would be a bad idea from c# consider what would happen if two threads launched two processes at the same time).

Instead you have a decent API for interacting with the child process, the idiomatic equivalent is the following:

using (Process process = new Process())
{
    process.StartInfo = startInfo;
    process.Start();
    // only if you need the output for debugging
    //string output = process.StandardOutput.ReadToEnd();
    process.WaitForExit();
    return process.ExitCode;
}

Note here (as with the other answer) that you must first wait for the process to exit before you can look at the exit code.

ShuggyCoUk
Why was this downvoted? It's the same answer as mine - although I think that the first part is a misunderstanding of the question?
Benjamin Podszun
I was explaining *why* his attempt to read the ERRORLEVEL (even if it was a 'normal' environment variable) was doomed to failure (along with the not waiting for exit).Obviously someone either thought I wasn't aware of this or thought I failed to explain that sufficiently clearly. I will revise to make it clearer
ShuggyCoUk
You are absolutely right, I was looking at a batch script. Many thanks, and I've upvoted the answer because it was very helpful to me.
Colin