从 C# 应用程序中托管的 powershell 中分离进程

Detaching process from powershell hosted in C# application

我们有一个执行 PowerShell 脚本的 C# 应用程序作为扩展点,我们无权更改此代码,但大致如下:

string command = @"C:\temp.ps1";
var fileName = "powershell";
var args = $"-ExecutionPolicy unrestricted . '{command}'";

var process = CreateProcess(fileName, args);
ExecuteProcess(ref process);

private Process CreateProcess(string fileName, string args)
{
    return new Process
    {
        StartInfo =
        {
            FileName = fileName,
            Arguments = args,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false
        }
    };
}

private int ExecuteProcess(ref Process proc)
{
    proc.Start();

    string text = string.Empty;
    string text2 = string.Empty;
    while (!proc.HasExited)
    {
        Thread.Sleep(1000);
        text += proc.StandardOutput.ReadToEnd();
        text2 += proc.StandardError.ReadToEnd();
    }
    proc.WaitForExit();
    text2 += proc.StandardError.ReadToEnd();
    text += proc.StandardOutput.ReadToEnd();

    Console.WriteLine(text);
    Console.WriteLine(text2);

    return proc.ExitCode;
}

我们有一个从这段代码执行的 PowerShell 脚本,它有一个漫长的 运行ning 过程,为了简单起见,我们只使用 ping.exe-t参数。

ping -t google.com

我们希望能够 fork ping.exe 进程,以便 c# 应用程序可以尽快恢复执行,并且本示例中的 ping.exe 继续以其愉快的方式运行。

我已经尝试在 powershell 脚本中 运行 Start-Process 但这仍然只是阻止 C# 应用程序的执行,直到所有进程都完全执行(所以它最终 运行s 完成):

Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log"

我也尝试过 运行 Start-Job 并将启动过程包装在一个单独的作业中,但是,这似乎启动了作业但从未完成

Start-Job -ScriptBlock { Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log" }

是否有任何方法可以从 PowerShell 中启动新进程并允许 C# 应用程序继续执行?

我找到了一个解决方法 - 如果我将 -Verb Open 传递给 Start-Process,它似乎会立即恢复对 C# 应用程序的执行。唯一的问题是您无法将标准输出或错误重定向到文件。

Start-Process ping -ArgumentList "-t","google.com" -Verb Open