使用systemdiagnostics.process在Powershell中运行后台作业

时间:2010-07-07 14:31:06

标签: .net powershell background jobs

我知道Powershell具有Start-JobWait-Job等后台工作功能,但可以使用.Net中Process的{​​{1}}类来实现同一件事情?如果是这样,最好的方法是什么/它对运行后台作业的默认Powershell机制有什么好处?

2 个答案:

答案 0 :(得分:2)

您当然可以使用Process对象以异步方式“启动”可执行文件,并且使用您获得的进程对象,您可以测试以查看EXE是否已完成或终止进程。诀窍是获取输出和错误流信息,而不会在程序运行时干扰控制台,这样你就可以做其他事情了。从MSDN文档中,看起来使用BeginOutputReadLine可能会解决问题:

// Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "Write500Lines.exe";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

虽然如果你想要后台行为,你需要在后台线程上执行StandardOutput.ReadToEnd(),然后创建一个机制来从主控制台线程中检索该输出,这似乎是很多工作,目前我可以想到任何优于PowerShell后台作业的优势。

另一种方法是创建一个运行空间来执行bg作业,因为blog post by Jim Truher指出了这一点。

答案 1 :(得分:0)

这不是优雅或有据可查。它创建一个System.Diagnostic.Process对象并对其执行一些常见的初始化。获得Process对象后,可以对其执行其他调整,然后调用Process.Start启动该过程。

function New-Process($cmd, $arguments, [switch]$stdout, [switch]$stdin, [switch]$stderr, [switch]$shellexec, [switch]$showwindow)
{
    $process = New-Object "System.Diagnostics.Process"
    $startinfo = New-Object "System.Diagnostics.ProcessStartInfo"

    $startinfo.FileName = $cmd
    $startinfo.Arguments = $arguments
    $startinfo.WorkingDirectory = $pwd.Path
    $startinfo.UseShellExecute = $shellexec
    $startinfo.RedirectStandardInput = $stdin
    $startinfo.RedirectStandardOutput = $stdout
    $startinfo.RedirectStandardError = $stderr

    if (!$showwindow) {
        $startinfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
    }

    $process.StartInfo = $startinfo

    return $process
}