我正在实现一个 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());
}
}
Run Code Online (Sandbox Code Playgroud)
然后我使用以下方法来知道脚本的所有执行何时完成。由于我通过检查管道的调用状态是否完成来执行此操作,因此我无法为脚本的每次执行创建一个新管道:
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);
}
Run Code Online (Sandbox Code Playgroud)
所以,要解决我的问题:
1)我可以强制管道在执行每个命令后产生输出吗?或者,
2)如果我每次运行命令时都创建一个新管道,是否有另一种方法可以检查脚本的所有执行是否已完成?
PowerShell在 C# 中使用实际类的示例很少,我对线程几乎一无所知,因此将不胜感激。
我觉得回答自己的问题很愚蠢,但我所做的只是将循环功能从 C# 代码移到我的脚本中,并且有效。所以现在我一次将所有键和值作为数组参数传递,并且管道中只有一个命令。
不过,我仍然有兴趣知道在执行管道中的每个命令后是否可以产生输出。
| 归档时间: |
|
| 查看次数: |
3234 次 |
| 最近记录: |