C# WinForms捕获命令行错误时触发异常,寻求解决方案
问题描述
我在C# Windows Forms应用里尝试执行加密/解密命令(调用aspnet_regiis.exe),想要捕获命令执行的错误输出,但遇到了问题。
第一次尝试的代码
直接调用目标程序,但读取错误输出时报错:
var p = Process.Start( @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe", action + @" " + section + " " + path + " " ); string errorInfoIfAny = p.StandardError.ReadToEnd().TrimEnd();
报错信息:StandardError has not been redirected.
测试参数:
action= "-peff" (故意输入错误参数触发报错) section = "appSettings" path= 任意文件夹路径
第二次尝试的代码
改为通过cmd.exe调用,但依旧无法正常捕获错误输出:
Process p = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo() { // CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, WorkingDirectory = Environment.CurrentDirectory }; startInfo.FileName = "cmd.exe"; startInfo.Arguments = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe" + " " + action + @" " + section + " " + path + " "; // cmd.exe spesific implementation p.StartInfo = startInfo; p.Start(); string errorInfoIfAny = p.StandardError.ReadToEnd().TrimEnd();
解决方案
问题原因
- 第一次代码没有开启错误输出重定向配置,直接读取
StandardError必然报错。 - 第二次代码用
cmd.exe中转时,缺少/c参数——cmd.exe需要这个参数来执行指定命令后退出,否则目标程序的输出无法正确传递到当前进程的重定向流中。
修正后的代码(推荐直接调用目标程序)
不需要通过cmd.exe中转,直接配置ProcessStartInfo开启重定向即可:
Process p = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe", Arguments = $"{action} {section} {path}", UseShellExecute = false, // 必须设为false才能启用输出重定向 RedirectStandardError = true, // 开启错误输出重定向 RedirectStandardOutput = true, // 可选,如果需要捕获正常输出也开启 CreateNoWindow = true // 可选,隐藏命令行窗口,适合WinForms场景 }; p.StartInfo = startInfo; p.Start(); // 注意:必须先读取输出流,再等待进程退出,避免缓冲区满导致死锁 string errorOutput = p.StandardError.ReadToEnd().TrimEnd(); string standardOutput = p.StandardOutput.ReadToEnd().TrimEnd(); p.WaitForExit(); // 处理捕获到的错误信息 if (!string.IsNullOrEmpty(errorOutput)) { MessageBox.Show($"执行错误:{errorOutput}"); }
若必须通过cmd.exe调用的修正方案
如果因为特殊需求要通过cmd.exe执行,需修改参数格式,添加/c并包裹命令:
// 其他配置不变,只修改Arguments string fullCommand = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe" + " " + action + " " + section + " " + path; startInfo.Arguments = $"/c \"{fullCommand}\""; // 用/c让cmd执行后退出,引号避免路径含空格出错
内容的提问来源于stack exchange,提问作者sandeep.mishra
相关产品推荐
相关产品推荐

