【问题标题】:Detaching process from powershell hosted in C# application从 C# 应用程序中托管的 powershell 中分离进程
【发布时间】:2017-10-30 23:53:01
【问题描述】:

我们有一个执行 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 脚本,该脚本从该代码执行,该代码有一个长时间运行的过程,为了简单起见,我们将使用 ping.exe-t 参数。

ping -t google.com

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

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

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# 应用程序继续执行?

【问题讨论】:

  • 既然可以do it directly,为什么还要从PowerShell运行ping.exe
  • Ping 只是一个例子,我们在 PowerShell 脚本中启动了其他进程,但不希望它阻塞
  • 但是你为什么要运行 PowerShell?只需生成您要运行的可执行文件。
  • 就像我在问题中所说,我们无权访问运行 PowerShell 代码的 C# 应用程序,我们所拥有的只是可以运行的 PowerShell 脚本。
  • Start-Process 异步运行一个进程。如果 C# 程序仍然阻塞,那么它一定是在等待由 PowerShell 进程启动的进程。

标签: c# powershell process start-job start-process


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多