I am using following code to write the PATH, EXECUTABLE NAME and ARGUMENTS to a batch file and execute it through CMD using c#. The problem is sometimes the application dosent starts up after executing the batch file. And the c# code dosent give me exception or any notification.
For which i want to get the Exitcode from CMD to determine if the commands executed properly. How can i determine Exit code ?
public void Execute()
{
try
{
string LatestFileName = GetLastWrittenBatchFile();
if (System.IO.File.Exists(BatchPath + LatestFileName))
{
System.Diagnostics.ProcessStartInfo procinfo = new System.Diagnostics.ProcessStartInfo("cmd.exe");
procinfo.UseShellExecute = false;
procinfo.RedirectStandardError = true;
procinfo.RedirectStandardInput = true;
procinfo.RedirectStandardOutput = true;
System.Diagnostics.Process process = System.Diagnostics.Process.Start(procinfo);
System.IO.StreamReader stream = System.IO.File.OpenText(BatchPath + LatestFileName);
System.IO.StreamReader sroutput = process.StandardOutput;
System.IO.StreamWriter srinput = process.StandardInput;
while (stream.Peek() != -1)
{
srinput.WriteLine(stream.ReadLine());
}
Log.Flow_writeToLogFile("Executed .Bat file : " + LatestFileName);
process.WaitForExit(1000);
if (process.ExitCode != 0)
{
int iExitCode = process.ExitCode;
}
stream.Close();
process.Close();
srinput.Close();
sroutput.Close();
}
else
{
ExceptionHandler.writeToLogFile("File not found");
}
}
catch (Exception ex)
{
ExceptionHandler.writeToLogFile(System.Environment.NewLine + "Target : " + ex.TargetSite.ToString() + System.Environment.NewLine + "Message : " + ex.Message.ToString() + System.Environment.NewLine + "Stack : " + ex.StackTrace.ToString());
}
}
_________________Update___________________
script inside Batchfile : [Note that Notepads.exe is wrong to get the error ]
START Notepads.EXE
"if "%ERRORLEVEL%" == "1" exit /B 1"
It is much easier to run the process directly instead of using creating a batch file that you later execute since you lose some control since you are using a batch script layer.
Use this code instead:
/// <summary>
/// Execute external process.
/// Block until process has terminated.
/// Capture output.
/// </summary>
/// <param name="binaryFilename"></param>
/// <param name="arguments"></param>
/// <param name="currentDirectory"></param>
/// <param name="priorityClass">Priority of started process.</param>
/// <returns>stdout output.</returns>
public static string ExecuteProcess(string binaryFilename, string arguments, string currentDirectory, ProcessPriorityClass priorityClass)
{
if (String.IsNullOrEmpty(binaryFilename))
{
return "no command given.";
}
Process p = new Process();
p.StartInfo.FileName = binaryFilename;
p.StartInfo.Arguments = arguments;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
if (!String.IsNullOrEmpty(currentDirectory))
p.StartInfo.WorkingDirectory = currentDirectory;
p.StartInfo.CreateNoWindow = false;
p.Start();
// Cannot set priority process is started.
p.PriorityClass = priorityClass;
// Must have the readToEnd BEFORE the WaitForExit(), to avoid a deadlock condition
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
if (p.ExitCode != 0)
{
throw new Exception(String.Format("Process '{0} {1}' ExitCode was {2}",
binaryFilename,
arguments,
p.ExitCode));
}
//string standardError = p.StandardError.ReadToEnd();
//if (!String.IsNullOrEmpty(standardError))
//{
// throw new Exception(String.Format("Process '{0} {1}' StandardError was {2}",
// binaryFilename,
// arguments,
// standardError));
//}
return output;
}
I use it in a number of projects and it works like a charm.
If you HAVE to go the batch script route, make sure that the batch script set exitcode properly.
Does the Process.ExitCode
property not give you what you want? Obviously you'd need to make sure that the batch file itself exits with the right exit code, mirroring the application it's running.
By the way, you should use using
statements to make sure that all the relevant streams are closed in the face of exceptions - and I would suggest the asynchronous ways of reacting to data from the application, rather than synchronous IO. If you do stick to synchronous IO, you should have another thread reading from standard error - otherwise if the process writes a lot of data to standard error, it will block waiting for you to clear the buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With