在.NET Process中调用PowerShell脚本执行livingdoc失败问题
问题:.NET Process调用PowerShell脚本运行livingdoc命令异常,直接运行正常
直接运行PowerShell脚本可正常生成HTML报告,但通过.NET Process调用时无预期结果;仅执行livingdoc --version的简单脚本可正常运行。
提供的代码
正常运行的PowerShell脚本(testLivingdoc.ps1)
$livingDocPath = "C:\Users\chris\.dotnet\tools\livingdoc.exe" $dllPath = "C:\Mylib\bin\Release\net6.0-windows\Mylib.dll" $jsonPath = "C:\Mylib\bin\Release\net6.0-windows\TestExecution.json" $command = "test-assembly" $parameter = "-t" & $livingDocPath $command $dllPath $parameter $jsonPath
.NET Process调用代码
static void Main(string[] args) { var binFolder = @"C:\Users\chris\Desktop\powershell"; var arguments = Path.Combine(binFolder, "testLivingdoc.ps1"); arguments = "-command " + arguments; Console.WriteLine($"script start with argument: {arguments}"); var startInfo = new ProcessStartInfo { FileName = @"powershell", Arguments = arguments, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = false }; using var p = Process.Start(startInfo); var stdError = p.StandardError.ReadToEnd(); var stdOutput = p.StandardOutput.ReadToEnd(); p.WaitForExit(); if (!string.IsNullOrEmpty(stdError)) Console.WriteLine($"powershell running error: {stdError}"); if (!string.IsNullOrEmpty(stdOutput)) Console.WriteLine($"powershell running result: {stdOutput}"); }
可正常运行的简单测试脚本
$livingDocPath = "C:\Users\chris\.dotnet\tools\livingdoc.exe" & $livingDocPath --version
原因分析
- 工作目录不一致:直接运行PowerShell时的工作目录与.NET Process默认启动的工作目录不同(后者通常是进程启动的项目bin目录),livingdoc可能依赖工作目录生成输出文件,或某些隐式路径解析失败。
- PowerShell参数传递不规范:使用
-command调用脚本时,未对路径做引号包裹处理(即使当前路径无空格,规范处理可避免潜在解析错误);且-command更适合执行代码片段,用-File直接调用脚本文件参数传递更稳定。 - 标准流读取顺序导致死锁:先读取错误流再读取输出流的同步读取方式,可能因缓冲区满导致进程阻塞,无法正常执行完成。
解决方案
方案1:指定正确的工作目录
在ProcessStartInfo中设置工作目录为脚本所在目录,确保livingdoc在预期路径下运行:
var startInfo = new ProcessStartInfo { FileName = @"powershell", Arguments = arguments, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = false, WorkingDirectory = binFolder // 设置为脚本所在目录 };
方案2:改用-File参数调用脚本
替换-command为-File,并对脚本路径做引号包裹,避免路径解析问题:
var arguments = Path.Combine(binFolder, "testLivingdoc.ps1"); arguments = $"-File \"{arguments}\"";
方案3:修正标准流读取方式,避免死锁
改用异步事件处理方式读取输出和错误流,防止进程阻塞:
using var p = Process.Start(startInfo); StringBuilder outputBuilder = new StringBuilder(); StringBuilder errorBuilder = new StringBuilder(); p.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) outputBuilder.AppendLine(e.Data); }; p.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) errorBuilder.AppendLine(e.Data); }; p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(); string stdOutput = outputBuilder.ToString(); string stdError = errorBuilder.ToString(); if (!string.IsNullOrEmpty(stdError)) Console.WriteLine($"powershell running error: {stdError}"); if (!string.IsNullOrEmpty(stdOutput)) Console.WriteLine($"powershell running result: {stdOutput}");
方案4:显式指定livingdoc输出路径
在PowerShell脚本中添加输出路径参数,强制livingdoc生成到指定目录:
$outputPath = "C:\Mylib\bin\Release\net6.0-windows\TestReport.html" & $livingDocPath $command $dllPath $parameter $jsonPath -o $outputPath
优先尝试方案1和方案2,这是此类问题的最常见诱因;若仍未解决,通过方案3获取完整的错误输出,进一步排查具体问题。
内容的提问来源于stack exchange,提问作者Chris Bao
相关产品推荐
相关产品推荐

