如何在C# WinForms中捕获PowerShell脚本执行时的每行代码?
解决方案:逐行捕获PowerShell脚本执行代码
核心思路
不要直接执行整个脚本文件,而是逐行读取脚本内容并逐行执行,同时记录每一行的执行信息,以此实现类似CNC HMI的实时行级监控需求。
具体实现步骤
1. 逐行读取脚本文件
使用File.ReadLines()方法逐行加载脚本内容,避免一次性将整个文件读入内存:
var scriptLines = File.ReadLines(@"C:\your\script\path\script.ps1");
2. 初始化PowerShell执行环境
创建PowerShell实例,按需配置执行策略、加载模块等:
using (var ps = PowerShell.Create()) { // 可选:设置进程级执行策略(根据场景调整) ps.AddCommand("Set-ExecutionPolicy") .AddArgument("RemoteSigned") .AddParameter("Scope", "Process") .Invoke(); ps.Commands.Clear(); // 清空初始化命令,准备执行脚本行
3. 逐行执行并捕获信息
遍历每一行脚本,执行后记录该行内容、执行结果或错误:
foreach (var line in scriptLines) { // 跳过空行和注释行(可选,按需调整) if (string.IsNullOrWhiteSpace(line) || line.TrimStart().StartsWith("#")) continue; // 执行当前行 ps.AddScript(line); var results = ps.Invoke(); // 记录执行信息:可根据需求输出到UI或日志 UpdateExecutionLog($"执行行: {line}"); // 捕获并记录错误 if (ps.Streams.Error.Any()) { foreach (var err in ps.Streams.Error) { UpdateExecutionLog($"错误: {err.ToString()}"); } ps.Streams.Error.Clear(); // 清空错误流,避免影响下一行执行 } ps.Commands.Clear(); // 清除当前命令,准备下一行执行 } }
4. WinForms UI实时更新
通过Invoke方法将执行信息同步到UI控件(如TextBox),避免跨线程操作异常:
// 假设存在名为txtExecutionLog的TextBox控件 private void UpdateExecutionLog(string message) { if (txtExecutionLog.InvokeRequired) { txtExecutionLog.Invoke(new Action<string>(UpdateExecutionLog), message); return; } txtExecutionLog.AppendText($"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}"); }
额外优化建议
- 处理多行命令:针对PowerShell中跨多行的语法(如脚本块、拆分的管道),可通过语法判断合并多行后执行,避免执行不完整代码报错。
- 执行状态跟踪:记录每一行的开始/结束时间、执行结果状态,方便后续追溯。
- 状态监听:订阅
PowerShell实例的InvocationStateChanged事件,捕获执行过程中的状态变化(如暂停、终止)。
内容的提问来源于stack exchange,提问作者sdgtc
相关产品推荐
相关产品推荐

