views:

43

answers:

1

Hi, I'm attempting to run a series of commands programmatically, read the error codes, and detect if these codes indicate success or failure so I can respond accordingly.

Currently my commands are using psexec which then launches robocopy. I've noted that while most commands return an error code of 0 if the program is successful, robocopy is odd in that it returns values in the range of 0-8 even if the operation is successful, so I am adding some extra logic in my error detection to note when robocopy returns an error code which otherwise suggests a failure.

The problem is that in this same set of commands I'm using PSExec to launch various other executables and batch files, so I need an error detection solution that allows me to know when robocopy is the one returning these error codes or if it's PSExec because an error code of 5 in robocopy is fine usually whereas an error code of 5 in PSExec says that access is denied.

So my question is, how do I know which program has returned the error code? I'm using c# .NET 4.0, and I'm using the Process class to programmatically launch these programs. I set the program name as psexec, and the arguments include the robocopy or other programs. I then run, wait for the exit, and store the error code, then attempt to parse it.

What do you all suggest?

Here is a code snippet:

foreach (var command in commands)
        {
            // TODO: Add exception handling
            string processName = command.Split(delimiters).ToList().ElementAt(0);    // split up command into pieces, select first "token" as the process name
            string commandArguments = command.Replace(processName + " ", ""); // remove the process name and following whitespace from the command itself, storing it in a new variable
            Process commandProcess = new Process(); // declare a new process to be used
            commandProcess.StartInfo.FileName = processName;    // add file start info for filename to process
            commandProcess.StartInfo.Arguments = commandArguments;  // add file start info for arguments to process
            commandProcess.StartInfo.UseShellExecute = false;  // skip permissions request
            commandProcess.Start();   // start process according to command's data
            commandProcess.WaitForExit();   // wait for the process to exit before continuing
            bool commandSuccessful = ParseCommandErrorCode(commandProcess, commandProcess.ExitCode);    // grab error code
            if (!commandSuccessful)
            {
                // ERROR! abort operation and inform the user of the last completed operation, and how many commands have not been run
            } // end if
            Console.WriteLine("Error code: {0}", commandProcess.ExitCode);    // print error code
            commandProcess.Close(); // close process
        } // end foreach
A: 

Haven't you already answered your own question? You will have to match the error code to success or failure for each utility. commandProcess.StartInfo.FileName will tell you if the utility launched was robocopy or PSExe. When parsing the error code, map the value to success or failure depending on the name of the file.

Rajorshi
The problem that I'm facing is that I always use PSExec to launch the programs, whether they be Robocopy or some other executable or batch file, so the file name is always psexec, but the arguments are always different. My question is how can I determine which of the programs has returned the code? Both PSExec and the other program are being executed - but before robocopy even executes PSExec could fail with an error code of 5 access denied - how can I determine which error code is coming from which program? or am I just kind of left guessing?
Ben
Ahh. Got it. Unfortunately, `PsExec` will return always success as long as is able to launch the application successfully irrespective of whether the application succeeded or failed. So whatever error code you get from launching PsExec will always be from PsExec. If that code indicates success only then you try to test for code from the actual application. One messy way to do that is to launch a script with `PsExec` which in turn launches your application, gets it's exit code and writes the code to a file. You can then read the code off the file.
Rajorshi
Thank you. it's as I feared :/ I think instead I'm going to do statistical analysis on the results and store the number of robocopy commands and compare them to the number of potentially failed commands in the range 0-8. If the number of failures equals or exceeds the number of robocopy commands, then the problem is almost certainly coming from PSExec/windows and I can warn the user. Otherwise I can just display the statistics and let the user decide if things are going according to plan or if they need to go investigate personally.
Ben