我正在尝试在PowerShell中启动一个进程(例如ping),设置执行时间限制,如果在截止时间之前没有终止该进程,则终止该进程。
我有一个脚本,可以启动一个进程并在x秒后终止它(简单),一个脚本可以启动一个进程,并在完成后从其StdOut中读取(简单)。
我的代码在x秒后停止进程
$p = Start-Process -FilePath "notepad" -PassThru
Wait-Process -InputObject $p -Timeout 3
Stop-Process -InputObject $p
我的代码来启动进程并从其StdOut中读取
$pinfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = "ping.exe"
Arguments = "-t 127.0.0.1"
RedirectStandardOutput = $true
UseShellExecute =$false
}
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$outevent = Register-ObjectEvent -Action {Write-Host $Event.SourceEventArgs.Data} -InputObject $p -EventName OutputDataReceived
$p.Start()
$p.BeginOutputReadLine()
但是我无法将这两个功能整合到一个脚本中。通常,StdOut读数会阻塞计时器。我想运行一个.exe x秒钟,然后读取当时生成的任何StdOut。
答案 0 :(得分:0)
I think you could achieve what you're looking for via background jobs. For example:
$Job = Start-Job -ScriptBlock {
ping.exe 8.8.8.8
}
$TimeOutSeconds = 5
1..$TimeoutSeconds | ForEach-Object {
$Job | Receive-Job
if (($Job | Get-Job).State -eq 'completed') {
Break
}
Else {
Start-Sleep 1
}
} -End { Write-Warning 'Timeout reached.' }
$Job | Receive-Job
Stop-Job $Job -PassThru | Remove-Job
Explanation:
Start-Job
cmdlet creates a background job that executes the defined script block. The cmdlet returns a PSRemotingJob
object that we return to $Job
to use to reference the job elsewhere in the script.ForEach-Object
loop is use to iterate 5 times with a 1 second delay on each iteration and each time uses the Receive-Job
cmdlet to retrieve any output that the background job has produced.-End
scriptblock of the ForEach-Object
is never executed.-End
block executes and warns the user that we've reached the timeout.