Использование 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
}