问题描述
我已经用C#编写了一段代码,以使用System.Management.Automation
执行Powershell脚本(特别是Azure PowerShell). Powershell脚本基本上将vhd上载到Azure上的容器中,当通过azure Powershell手动输入命令时,它会显示上载进度和经过的时间等.通过代码,一切正常,但我想获取命令的结果/输出(即上传进度,经过的时间),在命令执行期间(即pipeline.invoke();
),这里是代码:
I have written a piece of code (in C#) to execute a Powershell script (specifically Azure PowerShell) using System.Management.Automation
. The powershell script basically uploads a vhd in a container on Azure, which shows the upload progress and time elapsed etc when command is manually entered through azure Powershell. Through code everything works fine but i want to get the result/output of a command (i.e. upload progress, time elapsed), during command execution (i.e. pipeline.invoke();
) here is the code:
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command myCommand = new Command(scriptPath);
foreach (var argument in arguments)
{
myCommand.Parameters.Add(new CommandParameter(argument.Key, argument.Value));
}
pipeline.Commands.Add(myCommand);
var results = pipeline.Invoke(); // i want to get results here (i.e. during command execution)
foreach (var psObject in results)
{
System.Diagnostics.Debug.Write(psObject.BaseObject.ToString());
}
请指导是否可以从Powershell检索实时输出.
Please guide if it is possible to retrieve live output from Powershell.
推荐答案
除非您的目标是PowerShell 1.0,否则无需手动设置运行空间和管道,只需创建 PowerShell
类代替:
Unless you're targeting PowerShell 1.0, there's no need to set up your runspace and pipeline manually, create an instance of the PowerShell
class instead:
PowerShell psinstance = PowerShell.Create();
psinstance.AddScript(scriptPath);
var results = psinstance.Invoke();
更简单.
现在,PowerShell
类通过 Streams
属性,因此您可以订阅它,就像这样:
Now, the PowerShell
class exposes the various non-standard output streams (Verbose, Debug, Error etc.) - including the Progress Stream - via the Streams
property so you can subscribe to it, like so:
psinstance.Streams.Progress.DataAdded += myProgressEventHandler;
然后在您的事件处理程序中:
And then in your event handler:
static void myProgressEventHandler(object sender, DataAddedEventArgs e)
{
ProgressRecord newRecord = ((PSDataCollection<ProgressRecord>)sender)[e.Index];
if (newRecord.PercentComplete != -1)
{
Console.Clear();
Console.WriteLine("Progress updated: {0}", newRecord.PercentComplete);
}
}
作为一个示例,下面是上面显示的事件处理程序的运行情况,同时运行了一个示例脚本,该脚本在一个简单的控制台应用程序中写入进度信息(下面发布了示例脚本):
As an example, here is that event handler shown above in action, while running a sample script that writes progress information (sample script posted below) in a simple console application:
function Test-Progress
{
param()
Write-Progress -Activity 'Testing progress' -Status 'Starting' -PercentComplete 0
Start-Sleep -Milliseconds 600
1..10 |ForEach-Object{
Write-Progress -Activity "Testing progress" -Status 'Progressing' -PercentComplete $(5 + 6.87 * $_)
Start-Sleep -Milliseconds 400
}
Write-Progress -Activity 'Testing progress' -Status 'Ending' -PercentComplete 99
Start-Sleep -Seconds 2
Write-Progress -Activity 'Testing progress' -Status 'Done' -Completed
}
Test-Progress
这篇关于通过代码调用时获取Powershell命令的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!