连续执行 运行 PowerShell 命令并将结果写入表格
Execute a continuously running PowerShell command and get result into form
我有一个命令(实际上是一个 DAPR 命令 :-)),在 PowerShell 中 运行 并连续 return 结果。
我知道如何连接到 PowerShell 终端并获得结果,但我的问题是我的命令不断 returns 结果,我需要将此结果捕获到表单中。
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.AddScript("ping 172.21.1.25 -t");
powerShell.AddCommand("Out-String");
Collection<PSObject> PSOutput = powerShell.Invoke();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in PSOutput)
{
stringBuilder.AppendLine(pSObject.ToString());
}
return stringBuilder.ToString();
}
您无需等待管道到达 return - 您可以在输出仍然 运行 时开始使用输出!
您只需要进行一些更改:
- 将
-Stream
开关参数添加到 Out-String
(或完全删除 Out-String
)
- 创建一个
PSDataCollection<string>
实例,我们可以通过它收集输出
- 异步调用管道,
PowerShell.BeginInvoke<TInput, TOutput>()
void PingForever()
{
using (var powerShell = PowerShell.Create())
{
// prepare commands - notice we use `Out-String -Stream` to avoid "backing up" the pipeline
powerShell.AddScript("ping 8.8.8.8 -t");
powerShell.AddCommand("Out-String").AddParameter("Stream", true);
// now prepare a collection for the output, register event handler
var output = new PSDataCollection<string>();
output.DataAdded += new EventHandler<DataAddedEventArgs>(ProcessOutput);
// invoke the command asynchronously - we'll be relying on the event handler to process the output instead of collecting it here
var asyncToken = powerShell.BeginInvoke<object,string>(null, output);
if(asyncToken.AsyncWaitHandle.WaitOne()){
if(powerShell.HadErrors){
foreach(var errorRecord in powerShell.Streams.Error){
// inspect errors here
// alternatively: register an event handler for `powerShell.Streams.Error.DataAdded` event
}
}
// end invocation without collecting output (event handler has already taken care of that)
powerShell.EndInvoke(asyncToken);
}
}
}
void ProcessOutput(object? sender, DataAddedEventArgs eventArgs)
{
var collection = sender as PSDataCollection<string>;
if(null != collection){
var outputItem = collection[eventArgs.Index];
// Here's where you'd update the form with the new output item
Console.WriteLine("Got some output: '{0}'", outputItem);
}
}
我有一个命令(实际上是一个 DAPR 命令 :-)),在 PowerShell 中 运行 并连续 return 结果。 我知道如何连接到 PowerShell 终端并获得结果,但我的问题是我的命令不断 returns 结果,我需要将此结果捕获到表单中。
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.AddScript("ping 172.21.1.25 -t");
powerShell.AddCommand("Out-String");
Collection<PSObject> PSOutput = powerShell.Invoke();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in PSOutput)
{
stringBuilder.AppendLine(pSObject.ToString());
}
return stringBuilder.ToString();
}
您无需等待管道到达 return - 您可以在输出仍然 运行 时开始使用输出!
您只需要进行一些更改:
- 将
-Stream
开关参数添加到Out-String
(或完全删除Out-String
) - 创建一个
PSDataCollection<string>
实例,我们可以通过它收集输出 - 异步调用管道,
PowerShell.BeginInvoke<TInput, TOutput>()
void PingForever()
{
using (var powerShell = PowerShell.Create())
{
// prepare commands - notice we use `Out-String -Stream` to avoid "backing up" the pipeline
powerShell.AddScript("ping 8.8.8.8 -t");
powerShell.AddCommand("Out-String").AddParameter("Stream", true);
// now prepare a collection for the output, register event handler
var output = new PSDataCollection<string>();
output.DataAdded += new EventHandler<DataAddedEventArgs>(ProcessOutput);
// invoke the command asynchronously - we'll be relying on the event handler to process the output instead of collecting it here
var asyncToken = powerShell.BeginInvoke<object,string>(null, output);
if(asyncToken.AsyncWaitHandle.WaitOne()){
if(powerShell.HadErrors){
foreach(var errorRecord in powerShell.Streams.Error){
// inspect errors here
// alternatively: register an event handler for `powerShell.Streams.Error.DataAdded` event
}
}
// end invocation without collecting output (event handler has already taken care of that)
powerShell.EndInvoke(asyncToken);
}
}
}
void ProcessOutput(object? sender, DataAddedEventArgs eventArgs)
{
var collection = sender as PSDataCollection<string>;
if(null != collection){
var outputItem = collection[eventArgs.Index];
// Here's where you'd update the form with the new output item
Console.WriteLine("Got some output: '{0}'", outputItem);
}
}