2

我知道 Powershell 具有 , 等的后台作业功能Start-JobWait-Job但是是否可以使用 .Net 中的ProcessSystem.Diagnostics来实现相同的目的?如果是这样,最好的方法是什么/与运行后台作业的默认 Powershell 机制相比,它有什么优势?

4

2 回答 2

2

您当然可以使用 Process 对象异步“启动”可执行文件,并使用返回的进程对象进行测试以查看 EXE 是否已完成或终止该进程。诀窍是在程序运行时在不干扰控制台的情况下获取输出和错误流信息,以便您可以做其他事情。从 MSDN 文档中,看起来使用BeginOutputReadLinemay 可以解决问题:

// 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 工作,正如Jim Truher 的这篇博客文章所指出的那样。

于 2010-07-07T16:28:57.647 回答
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
}
于 2010-07-07T15:01:07.900 回答