5

我正在实现一个 WPF 应用程序,它为字典中给出的每个键/值对执行一个 PowerShell 脚本,使用该对作为脚本参数。我将脚本的每次运行都存储为管道中的新命令。但是,这导致我只能在每次运行脚本后需要输出时从运行的最后一个命令中获取输出。我考虑过在每次执行脚本时创建一个新管道,但我需要知道脚本的所有执行何时完成。这是帮助解释我的问题的相关代码:

private void executePowerShellScript(String scriptText, Dictionary<String, String> args)
{
     // Create the PowerShell object.
     PowerShell powerShell = PowerShell.Create();

     // If arguments were given, add the script and its arguments.
     if (args != null)
     {
          foreach (KeyValuePair<String, String> arg in args)
          {
               powerShell.AddScript(scriptText);
               powerShell.AddArgument(arg.Key);
               powerShell.AddArgument(arg.Value);
          }
     }

     // Otherwise, just add the script.
     else
          powerShell.AddScript(scriptText);

     // Add the event handlers.
     PSDataCollection<PSObject> output = new PSDataCollection<PSObject>();
     output.DataAdded += new EventHandler<DataAddedEventArgs>(Output_DataAdded);
     powerShell.InvocationStateChanged +=
          new EventHandler<PSInvocationStateChangedEventArgs>(Powershell_InvocationStateChanged);

     // Invoke the pipeline asynchronously.
     IAsyncResult asyncResult = powerShell.BeginInvoke<PSObject, PSObject>(null, output);
}

private void Output_DataAdded(object sender, DataAddedEventArgs e)
{
     PSDataCollection<PSObject> myp = (PSDataCollection<PSObject>)sender;

     Collection<PSObject> results = myp.ReadAll();
     foreach (PSObject result in results)
     {
          Console.WriteLine(result.ToString());
     }
}

然后我使用以下方法知道脚本的所有执行何时完成。由于我通过检查管道的调用状态是否已完成来执行此操作,因此我无法为脚本的每次执行创建新的管道:

private void Powershell_InvocationStateChanged(object sender, PSInvocationStateChangedEventArgs e)
{
     switch (e.InvocationStateInfo.State)
     {
          case PSInvocationState.Completed:
               ActiveCommand.OnCommandSucceeded(new EventArgs());
               break;
          case PSInvocationState.Failed:
               OnErrorOccurred(new ErrorEventArgs((sender as PowerShell).Streams.Error.ReadAll()));
               break;
     }
     Console.WriteLine("PowerShell object state changed: state: {0}\n", e.InvocationStateInfo.State);
}

所以,要回答我的问题:

1)我可以强制管道在它执行的每个命令之后产生输出吗?或者,
2)如果我每次运行命令时都创建一个新管道,是否有另一种方法可以检查脚本的所有执行是否已完成?

在 C# 中使用实际类的例子很少PowerShell,我对线程几乎一无所知,所以任何帮助将不胜感激。

4

2 回答 2

4

回答自己的问题我觉得很傻,但我所做的只是将循环功能从我的 C# 代码移到我的脚本中,这很有效。所以现在我一次将所有键和值作为数组参数传递,并且管道中只有一个命令。

不过,我仍然想知道是否可以在管道中的每个命令执行后产生输出。

于 2012-06-28T12:28:18.470 回答
0

我有一种情况,我有一个管理 PowerShell 环境的对象,它需要一个脚本或一个模块和 cmdlet 并执行它,然后从原始模块中获取一个新的脚本或模块和 cmdlet 或 cmdlet 并执行它。每次执行某些操作时,我都需要返回结果。我通过在每次执行后清除命令队列来解决它:

powerShellInstance.Commands.Clear();

希望这可以帮助。

于 2016-12-01T23:18:45.790 回答