我有一个Java程序,我想从PowerShell脚本作为后台进程启动,类似于守护程序在Linux上运行的方式。 PowerShell脚本需要做几件事:
我在Linux上有一个shell脚本,可以像这样启动程序:
$ java -jar MyProgram.jar >console.out 2>console.err &
我希望使用PowerShell脚本在Windows上复制相同的行为。我尝试使用Start-Process
各种选项组合,以及创建System.Diagnostics.ProcessStartInfo
和System.Diagnostics.Process
个对象,但到目前为止我没有运气。 PowerShell作为后台进程启动程序,但是当启动PowerShell会话的DOS窗口关闭时,程序突然终止。我希望它在后台启动并独立于启动它的命令窗口。
输出重定向也很麻烦,因为输出和错误流似乎只能在同一窗口中运行的过程中重定向(例如,使用-NoNewWindow
)。
在PowerShell中这种事情是否可行?
答案 0 :(得分:18)
使用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'
答案 1 :(得分:2)
考虑使用任务调度程序。定义任务并设置它而不需要任何触发器。这将允许您简单地“运行”(手动触发)任务。
您可以使用ScheduledTasks powershell模块设置和/或触发计划任务,也可以使用GUI。
答案 2 :(得分:2)
这是一篇很老的帖子,但是因为我认为它很好,所以可能有助于分享。它是对'java'而不是'javaw'的调用,这可能是你的问题。使用我的JEdit java程序通过powershell启动它,然后自己动手。
var doneTodoIds = todos.filter(todo => todo.completed === true ).map( todo => todo.id).includes(this.state.checkedIds);
var result = arraysIntersect(doneTodoIds, this.state.checkedIds);
您可以将其转换为小功能,然后使用别名,以便在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"
答案 3 :(得分:0)
古老的问题,但是由于我有相同的目标,因此我使用了@use的答案来实现它。
这是我的代码:)
$NAME_TASK = "myTask"
$NAME_TASKPATH = "\myPath\"
if ($args[0] -eq "-task") {
# Code to be run "detached" here...
Unregister-ScheduledTask -TaskName $NAME_TASK -TaskPath $NAME_TASKPATH -Confirm:$False
Exit
}
$Task = (Get-ScheduledTask -TaskName $NAME_TASK -TaskPath $NAME_TASKPATH -ErrorAction 'SilentlyContinue')
if ($Task) {
Write-Host "ERR: Task already in progress"
Exit 1
}
$A = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy bypass -NoProfile -Command ""$PSCommandPath -task $args"""
Register-ScheduledTask -TaskName $NAME_TASK -TaskPath $NAME_TASKPATH -Action $A | Start-ScheduledTask