Try the following to see if it meets your needs--it shows how to use System.Diagnostics.Process
with exception handling and seems to avoid the issue that you mentioned. It's been tested, but whether or not it works for your case may depend on what other program you are calling and how the other program generates output.
Additionally, if you use a fully-qualified name for the program that you want to execute (ex: C:Windowssystem32ipconfig.exe), you can check to see if the file exists using System.IO.File.Exists
, prior to attempting to call it using "Process".
if (!System.IO.File.Exists(@"C:Windowssystem32ipconfig.exe))
{
System.Diagnostics.Debug.WriteLine("Error: Filename doesn't exist.");
//ToDo: add desired code here
}
Create a class (name: Helper)
Add the following using statements:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
Create two events to allow data to be sent to subscribers.
//delegates
public delegate void EventHandlerProcessErrorReceived(object sender, string data);
public delegate void EventHandlerProcessOutputReceived(object sender, string data);
//event that subscribers can subscribe to
public event EventHandlerProcessErrorReceived ProcessErrorReceived;
public event EventHandlerProcessOutputReceived ProcessOutputReceived;
Create two methods that we can call to pass data to subscribers:
- OnErrorReceived - raised when error messages are received
- OnOutputReceived - raised when standard output messages are received
Each method checks if there are any subscribers, and if any data exists. If so, the event is raised.
private void OnErrorReceived(string data)
{
//only raise event if there are subscribers and actual data exists
if (ProcessErrorReceived != null && !String.IsNullOrEmpty(data))
{
//raise event
ProcessErrorReceived(this, data);
}
}
private void OnOutputReceived(string data)
{
//only raise event if there are subscribers and actual data exists
if (ProcessOutputReceived != null && !String.IsNullOrEmpty(data))
{
//raise event
ProcessOutputReceived(this, data);
}
}
Create method that calls System.Diagnostics.Process (name: RunCmd)
RunCmd
public void RunCmd(string exePath, string arguments = null, Dictionary<string, string> environmentVarDict = null)
{
string errMsg = string.Empty;
try
{
if (String.IsNullOrEmpty(exePath))
{
errMsg = "Error: fullyQualifiedExePath not specified";
Debug.WriteLine("Error: " + errMsg);
OnErrorReceived(errMsg); //raise event
return;
}
//create new instance
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
//add environment variables, if specified
if (environmentVarDict != null)
{
foreach (KeyValuePair<string, string> kvp in environmentVarDict)
{
//add environment variable
startInfo.EnvironmentVariables[kvp.Key] = kvp.Value;
}
}
startInfo.Arguments = arguments; //arguments
startInfo.CreateNoWindow = true; //don't create a window
startInfo.RedirectStandardError = true; //redirect standard error
startInfo.RedirectStandardOutput = true; //redirect standard output
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
//startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
if (exePath.Contains("\"))
{
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(exePath);
}
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
{
//subscribe to event and add event handler code
p.ErrorDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
//Debug.WriteLine("Error: " + e.Data);
OnErrorReceived(errMsg); //raise event
}
};
//subscribe to event and add event handler code
p.OutputDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
//Debug.WriteLine("Output: " + e.Data);
OnOutputReceived(e.Data); //raise event
}
};
p.Start(); //start
p.BeginErrorReadLine(); //begin async reading for standard error
p.BeginOutputReadLine(); //begin async reading for standard output
//waits until the process is finished before continuing
p.WaitForExit();
}
}
catch(System.ComponentModel.Win32Exception ex)
{
errMsg = "Error (Win32Exception): " + ex.Message;
//Debug.WriteLine(errMsg);
OnErrorReceived(errMsg);
}
catch(Exception ex)
{
errMsg = "Error: " + ex.Message;
//Debug.WriteLine(errMsg);
OnErrorReceived(errMsg);
}
}
Helper.cs (complete code)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ProcessUsage
{
public class Helper
{
//delegates
public delegate void EventHandlerProcessErrorReceived(object sender, string data);
public delegate void EventHandlerProcessOutputReceived(object sender, string data);
//event that subscribers can subscribe to
public event EventHandlerProcessErrorReceived ProcessErrorReceived;
public event EventHandlerProcessOutputReceived ProcessOutputReceived;
private void OnErrorReceived(string data)
{
//only raise event if there are subscribers and actual data exists
if (ProcessErrorReceived != null && !String.IsNullOrEmpty(data))
{
//raise event
ProcessErrorReceived(this, data);
}
}
private void OnOutputReceived(string data)
{
//only raise event if there are subscribers and actual data exists
if (ProcessOutputReceived != null && !String.IsNullOrEmpty(data))
{
//raise event
ProcessOutputReceived(this, data);
}
}
public void RunCmd(string exePath, string arguments = null, Dictionary<string, string> environmentVarDict = null)
{
string errMsg = string.Empty;
try
{
if (String.IsNullOrEmpty(exePath))
{
errMsg = "Error: fullyQualifiedExePath not specified";
Debug.WriteLine("Error: " + errMsg);
OnErrorReceived(errMsg); //raise event
return;
}
//create new instance
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
//add environment variables, if specified
if (environmentVarDict != null)
{
foreach (KeyValuePair<string, string> kvp in environmentVarDict)
{
//add environment variable
startInfo.EnvironmentVariables[kvp.Key] = kvp.Value;
}
}
startInfo.Arguments = arguments; //arguments
startInfo.CreateNoWindow = true; //don't create a window
startInfo.RedirectStandardError = true; //redirect standard error
startInfo.RedirectStandardOutput = true; //redirect standard output
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
//startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
if (exePath.Contains("\"))
{
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(exePath);
}
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
{
//subscribe to event and add event handler code
p.ErrorDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
//Debug.WriteLine("Error: " + e.Data);
OnErrorReceived(errMsg); //raise event
}
};
//subscribe to event and add event handler code
p.OutputDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
//Debug.WriteLine("Output: " + e.Data);
OnOutputReceived(e.Data); //raise event
}
};
p.Start(); //start
p.BeginErrorReadLine(); //begin async reading for standard error
p.BeginOutputReadLine(); //begin async reading for standard output
//waits until the process is finished before continuing
p.WaitForExit();
}
}
catch(System.ComponentModel.Win32Exception ex)
{
errMsg = "Error (Win32Exception): " + ex.Message;
//Debug.WriteLine(errMsg);
OnErrorReceived(errMsg);
}
catch(Exception ex)
{
errMsg = "Error: " + ex.Message;
//Debug.WriteLine(errMsg);
OnErrorReceived(errMsg);
}
}
}
}
Usage:
Helper helper = new Helper();
//subscribe to event and add event handler
helper.ProcessErrorReceived += (s, data ) =>
{
Debug.WriteLine("helper.ProcessErrorReceived: " + data);
};
//subscribe to event and add event handler
helper.ProcessOutputReceived += (s, data) =>
{
Debug.WriteLine("helper.ProcessOutputReceived: " + data);
};
Example 1:
helper.RunCmd("test");
Example 2:
helper.RunCmd("ipconfig", "/all");
Example 3:
helper.RunCmd(@"C:Windowssystem32ipconfig.