Использование systemdiagnostics.process для запуска фоновых заданий в Powershell

Я знаю, что Powershell имеет фоновую работу с Start-Job, Wait-Jobи т. д., но можно ли использовать Process класс от System.Diagnostics в.Net добиться того же? Если это так, что будет лучшим способом сделать это / какие преимущества он будет иметь по сравнению со стандартным механизмом Powershell для выполнения фоновых заданий?

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, как отмечается в этом посте Джима Трухера.

Это не элегантно или хорошо документировано. Он создает объект 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
}
Другие вопросы по тегам