基于C#语言,调用cmd控制台,执行其他exe程序效率比较,分为3种方式:
- 后台静默同步执行exe程序
- 后台静默异步执行exe程序
- 后台显示cmd窗口执行
写了一个输出1-100数字的控制台exe程序,输出完之后,系统等待20秒,总耗时应该20秒多一点,比较效率的代码为:
Stopwatch watch = new Stopwatch();
watch.Start();
string exePath = "D:\\VSApplication\\ExeTestCSharp\\ExeTestCSharp\\bin\\Release\\ExeTestCSharp.exe";
string result = QConsoleTest.QCmdShell.ExecuteCmdShell(exePath, "-GUID", "QCJ");
watch.Stop();
Console.WriteLine("同步:" + watch.Elapsed.TotalSeconds);
Console.WriteLine(result);
watch.Restart();
string sb = QConsoleTest.QCmdShell.ExecuteCmdShellAsync(exePath, "-GUID", "2");
watch.Stop();
Console.WriteLine("异步:" + watch.Elapsed.TotalSeconds);
Console.WriteLine(sb);
watch.Restart();
string res = QConsoleTest.QCmdShell.ExecuteCmdShellHasWindow(exePath,true, "-GUID", "3");
watch.Stop();
Console.WriteLine("显示窗口:" + watch.Elapsed.TotalSeconds);
Console.WriteLine(res);
输出结果:
可见,异步调用最快,显示窗口最慢,后台静默调用可以获取控制台exe程序本身控制台输出的结果或者错误信息,而显示窗口方式会直接打开ExeTestCSharp.exe的控制台窗口,测试的控制台ConsoleTest并不能获取被调用的控制台上输出的信息。
异步调用时,可以在OutputDataReceived事件中与主程序控件联动。
所以推荐使用异步调用窗口,源码为:
private static StringBuilder sData = new StringBuilder();
/// <summary>
/// 异步执行命令行程序
/// </summary>
/// <param name="cmdShellPath"></param>
/// <param name="inputArguments"></param>
/// <returns></returns>
public static string ExecuteCmdShellAsync(string cmdShellPath, params string[] inputArguments)
{
sData.Clear();
string shellMsg = "";
string argus = inputArguments.Where(arg => string.IsNullOrEmpty(arg) == false).Aggregate("", (current, arg) => current + arg + " ");
argus = argus.Trim();
//创建进程对象
Process process = new Process();
//参数
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = cmdShellPath,
Arguments = argus,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = false,
RedirectStandardOutput = true, //将输出信息重定向,而不是默认的显示在dos控制台上
};
process.StartInfo = startInfo;
//添加事件
process.OutputDataReceived += OutputDataReceivedHandler;
try
{
if (!process.Start())
{
sData.Append("错误:程序未执行");
return sData.ToString();
}
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// 使当前线程等待,直到关联进程终止
process.WaitForExit();
}
catch (Exception exception)
{
shellMsg = "错误:" + exception.Message;
}
finally
{
process.Close();
process.Dispose();
process = null;
}
return sData.ToString().TrimEnd();
}
//异步数据接受响应事件
private static void OutputDataReceivedHandler(object sender, DataReceivedEventArgs e)
{
try
{
if (!string.IsNullOrEmpty(e.Data))
{
sData.Append(e.Data + Environment.NewLine);
}
}
catch (Exception ex)
{
sData.Append(ex.Message + Environment.NewLine);
}
}