5

スクリプト引数としてペアを使用して、辞書で指定された各キーと値のペアに対して PowerShell スクリプトを実行する WPF アプリケーションを実装しています。スクリプトの各実行を新しいコマンドとしてパイプラインに保存します。ただし、これにより、スクリプトを実行するたびに出力が必要な場合に、最後に実行されたコマンドからのみ出力が返されます。スクリプトが実行されるたびに新しいパイプラインを作成することを検討しましたが、スクリプトのすべての実行がいつ完了するかを知る必要があります。私の問題を説明するのに役立つ関連コードは次のとおりです。

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#コードからスクリプトに移動するだけでうまくいきました。そのため、すべてのキーと値を一度に配列パラメーターとして渡し、パイプラインに1つのコマンドしかありません。

ただし、パイプラインの各コマンドが実行された後に出力を生成できるかどうかを知りたいと思います。

于 2012-06-28T12:28:18.470 に答える