尝试以下操作,看看它是否满足您的需求——它展示了如何使用System.Diagnostics.Process 处理异常,并且似乎避免了您提到的问题。它已经过测试,但它是否适用于您的情况可能取决于您正在调用的其他程序以及其他程序如何生成输出。
此外,如果您对要执行的程序使用完全限定名称(例如:C:\Windows\system32\ipconfig.exe),您可以使用System.IO.File.Exists 检查文件是否存在,在尝试使用“进程”调用它之前。
if (!System.IO.File.Exists(@"C:\Windows\system32\ipconfig.exe))
{
System.Diagnostics.Debug.WriteLine("Error: Filename doesn't exist.");
//ToDo: add desired code here
}
创建一个类(名称:Helper)
添加以下 using 语句:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
创建两个事件以允许将数据发送给订阅者。
//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;
创建两个我们可以调用的方法将数据传递给订阅者:
- OnErrorReceived - 收到错误消息时引发
- OnOutputReceived - 在收到标准输出消息时引发
每个方法都会检查是否有订阅者,以及是否存在任何数据。如果是,则引发事件。
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);
}
}
创建调用 System.Diagnostics.Process 的方法(名称: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(完整代码)
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);
}
}
}
}
用法:
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);
};
示例 1:
helper.RunCmd("test");
示例 2:
helper.RunCmd("ipconfig", "/all");
示例 3:
helper.RunCmd(@"C:\Windows\system32\ipconfig.exe", "/all");
示例 4:
Dictionary<string, string> environmentVarsDict = new Dictionary<string, string>();
environmentVarsDict.Add("environmentVar1", "myValue1");
environmentVarsDict.Add("environmentVar2", "myValue2");
helper.RunCmd("test123", "/c", environmentVarsDict);