我目前正在try 获取我通过PowerShell运行的一个程序的标准输出.

我有这样的东西:

                    using var ps = PowerShell.Create();
                    ps.AddCommand("Start-Process")
                        .AddParameter("FilePath", somePath)
                        .AddParameter("ArgumentList", someArguments)
                        .AddParameter(...); //Adding some more parameters

                    var result = ps.Invoke<Process>();
                    result[0].StandardOutput //Always null

现在我想要标准yields ,但我好像买不到. 生成的流程有一个公共属性"StandardOutput",但它始终为空.

我知道我可以通过添加一个完整的PowerShell脚本来实现这一点,而不是添加PowerShell类提供的其他函数.

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "SomeFileName"
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "someArguments"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
Write-Host $stdout

不过,我不想这样做,因为在我的用例中,我将根据需要使用参数构建这些命令,并且我不想求助于字符串操作来构建我的命令.

推荐答案

Start-Process不产生输出,它通过-RedirectStandard*参数提供输出以将输出重定向到文件.如果您需要进程的输出,您应该在C#代码中使用Process类,就像在PowerShell代码中一样.可能也应该将PowerShell实例排除在等式之外,因为除非您想要使用WriteError,否则不需要它.

另一种 Select 是在PowerShell实例脚本中使用& operator同步运行该进程.

这两种方法都是非常粗略的测试示例,如果需要,您肯定应该实现错误处理和其他功能.

将定义保存在PowerShell变量中,即$def:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Management.Automation;

namespace Testing
{
    public static class Test
    {
        public static IEnumerable<string> RunWithProcess(string fileName, string[] args)
        {
            ProcessStartInfo psi = new ProcessStartInfo
            {
                UseShellExecute = false,
                RedirectStandardOutput = true,
                FileName = fileName,
                Arguments = string.Join(" ", args)
            };

            using (Process proc = new Process { StartInfo = psi })
            {
                proc.Start();
                proc.WaitForExit();

                while (!proc.StandardOutput.EndOfStream)
                {
                    yield return proc.StandardOutput.ReadLine();
                }
            }
        }

        public static Collection<PSObject> RunWithPwsh(string fileName, string[] args)
        {
            using (PowerShell ps = PowerShell.Create())
            {
                return ps.AddScript(@"
                    param($process, $arguments)

                    & $process @arguments")
                .AddParameter("process", fileName)
                .AddParameter("arguments", args)
                .Invoke();
            }
        }
    }
}
Add-Type -TypeDefinition $def

[Testing.Test]::RunWithPwsh('cmd.exe', ('/c', 'ping -n 10 google.com'))
[Testing.Test]::RunWithProcess('cmd.exe', ('/c', 'ping -n 10 google.com'))

Csharp相关问答推荐

Selenium C#嵌套循环

为什么使用DXGI输出复制和Direct 3D时捕获的图像数据全为零?

无法从具有一对多关系的C#类中使用Swagger创建记录

需要深入了解NpgSQL DateTimeOffset处理

为什么将鼠标悬停在DateTimeOffset上只显示Hour值?

S能够用DATETIME来计算,这有什么错呢?

使用预定义对象减少Task.Run/Factory.StartNew中的关闭开销

反序列化私有成员

C# CompareTo()和Compare()可以返回除-1和1以外的整数吗?

C#中浮点数的System.Text.Json序列化问题

LINQ to Entities中的加权平均值

.NET:从XPath定位原始XML文档中的 node

在C#中,是否有与变量DISARD对应的C++类似功能?

如何让游戏对象在切换场景时被销毁,但在开始新游戏时重新锁定

如何使用.NET Aspire从Blazor应用程序与GRPC API通信?

WPF如何获取有关从一个视图模型更改另一个视图模型的信息

无效的Zip文件-Zip存档

.NET EF Core Automapper项目到筛选不起作用

使用C#代码和SQL SERVER中的相同证书签名会产生不同的结果

读取测试项目中的应用程序设置