Запуск автономного фонового процесса в PowerShell
У меня есть программа Java, которую я хотел бы запустить в качестве фонового процесса из PowerShell script, аналогично тому, как демон работает в Linux. PowerShell script должен сделать несколько вещей:
- Запустите программу как отдельный и отсоединенный процесс в фоновом режиме, то есть родительское окно может быть закрыто и процесс будет работать.
- Перенаправить стандартный вывод программы и стандартную ошибку в файлы.
- Сохраните PID фонового процесса в файл, чтобы его можно было завершить позже другим script.
У меня есть оболочка script в Linux, которая запускает программу следующим образом:
$ java -jar MyProgram.jar >console.out 2>console.err &
Я надеюсь повторить то же поведение в Windows, используя PowerShell script. Я попытался использовать Start-Process
с различными комбинациями опций, а также с созданием объектов System.Diagnostics.ProcessStartInfo
и System.Diagnostics.Process
, но до сих пор мне не повезло. PowerShell запускает программу как фоновый процесс, но программа внезапно завершается, когда окно DOS, которое запустило сеанс PowerShell, закрыто. Я хотел бы, чтобы он начинался в фоновом режиме и не зависел от начального окна команды.
Перенаправление вывода также было проблематичным, так как кажется, что потоки вывода и ошибок могут быть перенаправлены только в процессе, выполняется в том же окне (например, используя -NoNewWindow
).
Возможно ли это в PowerShell?
Ответы
Ответ 1
Используйте jobs для этого:
Start-Job -ScriptBlock {
& java -jar MyProgram.jar >console.out 2>console.err
}
Другой вариант: Start-Process
:
Start-Process java -ArgumentList '-jar', 'MyProgram.jar' `
-RedirectStandardOutput '.\console.out' -RedirectStandardError '.\console.err'
Ответ 2
Это старый пост, но, поскольку я работаю, он думал, что это может помочь поделиться. Его призыв к "java" вместо "javaw", вероятно, относится к вашей проблеме. Выпустил сам, используя мою программу jEdit java через powershell, чтобы запустить ее.
#Requires -Version 3.0
$MyDriveRoot = (Get-Location).Drive.Root
$JEditDir = $($mydriveroot + "jEdit") ;# Should be C:\jEdit or wherever you want. JEdit is a sub-directory.
$jEdit = $($JEditDir + "\jedit.jar" )
$jEditSettings = $($JEditDir + "\settings")
$JEditLogs = $($JEditDir + "\logs")
Start-Process -FilePath javaw -ArgumentList ( '-jar',"$jEdit", '-settings="$JEditSettings"' ) -RedirectStandardOutput "$JEditLogs\console.out" -RedirectStandardError "$JEditLogs\console.err"
Что вы можете превратить в небольшую функцию, а затем в псевдоним, чтобы он легко запускался в Powershell.
If ( ( Test-Path $jedit) ) {
Function Start-JEdit() {
Start-Process -FilePath javaw -ArgumentList ( '-jar',"$jEdit", '-settings="$($mydriveroot + "jEdit\settings")"' ) -RedirectStandardOutput "$JEditLogs\console.out" -RedirectStandardError "$JEditLogs\console.err"
}
New-Alias -Name jedit -Force Start-JEdit -Description "Start JEdit programmers text editor"
}
Ответ 3
Подумайте о том, как использовать этот планировщик задач. Определите задачу и установите ее без каких-либо триггеров. Это позволит вам просто запустить "запустить" (вручную запустить) задачу.
Вы можете настроить и/или запустить запланированные задачи с помощью модуля powershell ScheduledTasks, или вы можете использовать графический интерфейс.