如何将Root Path捕获至变量?解决双CMD窗口及StandardOut异常问题
问题解答:以管理员权限执行logman命令的窗口显示与异常问题
先梳理下你的场景:你想用C#以管理员权限执行logman.exe PerfCounterCustom | findstr "Root"命令,捕获Root Path到变量,但现在出现两个CMD窗口,还抛出System.InvalidOperationException异常。下面分别解答你的两个问题:
1. 如何禁用CMD窗口的显示?
要隐藏窗口,你需要调整ProcessStartInfo的属性,这里要注意管理员权限(Verb="runas")要求UseShellExecute=true,这种情况下CreateNoWindow属性不生效,得用WindowStyle来控制窗口隐藏:
var proc = new Process { StartInfo = new ProcessStartInfo { FileName = @"C:\Windows\System32\cmd.exe", Arguments = "/c logman.exe PerfCounterCustom | findstr \"Root\"", Verb = "runas", UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden // 关键设置:隐藏窗口 } };
另外你原来的参数里用了cmd /k,/k会让CMD执行命令后保持窗口打开,改成/c的话,命令执行完成后窗口会自动关闭,也能避免多余窗口残留。
2. 异常产生的原因是什么?
你遇到的System.InvalidOperationException: StandardOut has not been redirected or the process hasn't started yet.异常,核心原因有两个:
- 未开启标准输出重定向:要读取
StandardOutput,必须将ProcessStartInfo的RedirectStandardOutput设为true; - 权限与重定向的冲突:当你设置
Verb="runas"(获取管理员权限)时,系统要求UseShellExecute=true,但**UseShellExecute=true和RedirectStandardOutput=true是互斥的**——系统通过Shell执行程序时,不支持重定向标准输入输出流。
解决矛盾的可行方案:
如果要同时实现管理员权限和捕获输出,你可以换个思路,把命令输出写入临时文件,再读取文件内容:
var tempFile = Path.GetTempFileName(); var proc = new Process { StartInfo = new ProcessStartInfo { FileName = @"C:\Windows\System32\cmd.exe", Arguments = $"/c logman.exe PerfCounterCustom | findstr \"Root\" > {tempFile}", Verb = "runas", UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden } }; proc.Start(); proc.WaitForExit(); // 等待命令执行完成 // 读取临时文件里的Root Path var rootPath = File.ReadAllText(tempFile).Trim(); // 记得清理临时文件 File.Delete(tempFile);
内容的提问来源于stack exchange,提问作者user584018
相关产品推荐
相关产品推荐

