.net 我如何捕获PowerShell行,因为它们是从c# winforms中的powershell脚本执行的

tnkciper  于 12个月前  发布在  .NET
关注(0)|答案(1)|浏览(153)

我目前正在开发一个.Net Framework C# WinForms应用程序,它使用System.Management.Automation执行PowerShell脚本。
当PowerShell脚本执行时,我希望有一种方法可以在脚本执行时捕获脚本中的每一行代码,而不是最初只是将整个文件作为字符串阅读。
我正在用这种方式构建一台机器,并希望它的功能类似于CNC机器的HMI
看起来Powershell.HistoryString()给出了历史,但我认为它只会一次全部归还。
让我知道如果我可以提供更多的信息.谢谢!

b1zrtrql

b1zrtrql1#

下面是一个最小的C#示例,使用**PowerShell SDKSystem.Management.Automation.Language.Parser**,PowerShell语言解析器:

限制

  • 这种简单的实现只在输入脚本自己的顶级语句上循环,并将 * 复合 * 语言语句(如foreachwhile)视为 * 单一 * 语句。
  • 嵌套处理是可能的 * 但有限制 *,[1]并且需要更多的努力。最终,这是 * 没有 * 替代IDE的调试器,允许您单步执行代码。
using System.Management.Automation;
using System.Management.Automation.Language;

static class Program {
  public static void Main() {

    // ADD YOUR SCRIPT FILE PATH HERE.
    var scriptFilePath = @"/path/to/your/script.ps1";

    // Parse the script file (error handling omitted).
    var ast = Parser.ParseFile(scriptFilePath, out _, out _);

    // Iterate over the script file's statements one by one, printing their
    // source code, followed by executing and printing their results.
    using (var ps = PowerShell.Create()) 
    {

      foreach (var stmt in ast.EndBlock.Statements)
      {
        // Print the statement's source code.
        Console.WriteLine(string.Format("» Executing:\n{0}\n\n»  Result:\n", stmt.ToString()));
        // Execute the statement and print its for-display formatted results, using
        // an aux. Out-String call.
        foreach (var o in ps.AddScript(string.Format(". {{ {0} }} | Out-String", stmt.ToString())).Invoke())
        {
          Console.WriteLine(o);
        }
        ps.Commands.Clear();
      }

    }

  }
}

字符串
语言解析器是需要的,因为PowerShell语句可以跨多行,所以你需要知道哪些行块构成了一个语句。
示例输出:

» Executing:
Get-ChildItem -File |
  Measure-Object Length -Sum -Maximum

»  Result:

Count             : 2
Average           :
Sum               : 1479
Maximum           : 1122
Minimum           :
StandardDeviation :
Property          : Length


» Executing:
Get-Date -Format yyyy

»  Result:

2023


[1]例如,foreach语句的AST表示是System.Management.Automation.Language.LoopStatementAst类型,它有一个.Condition和一个.Body属性,你必须单独调用这些属性,并决定何时执行主体。带有 labeledbreakcontinue语句的 * 嵌套 * 循环跨越语句边界,几乎不可能用这种方式处理。

相关问题