【问题标题】:PowerShell Background-Job Processing of a while loopwhile循环的PowerShell后台作业处理
【发布时间】:2016-02-22 09:31:32
【问题描述】:

我正在尝试查看后台作业中的进程,但我认为我无法正确理解 powershell 中的后台处理。我假设是因为我的脚本不想工作。

$target = "firefox"
$Watch = {
    while (1) {
    sleep -Milliseconds 100
        if(!((get-process $target -ErrorAction SilentlyContinue).Responding -eq $true)) 
        {
            Get-Job -name $target | Stop-Job
            break
        }
    }
}

Start-Job -Name $target -ScriptBlock $Watch

在我看来,这个脚本应该每 100 毫秒控制我的“firefox”进程的“响应”属性,如果 firefox 挂起或关闭,它应该停止后台作业。

如果我执行此脚本然后关闭我的 firefox 进程,则作业仍在运行。它似乎并不关心我的Stop-Job 命令。

如果我在没有任何类似工作的情况下执行这个 scipt,它就像一个魅力。

$target = "firefox"
while (1) {
    sleep -Milliseconds 100
        if(!((get-process $target -ErrorAction SilentlyContinue).Responding -eq $true)) 
        {
            Write-Host "Hello"
            break
        }
}

如果我使用作业运行此脚本,并在控制台中执行get-job -name $target | stop-job 部分,它也可以工作。所以它只是不想在作为后台作业运行时执行我的if () {scriptblock}

是否不可能在后台作业中运行循环?

【问题讨论】:

    标签: powershell jobs


    【解决方案1】:

    您正试图从作业内部停止作业...这是不可能的

    PowerShell 作业使用不同的进程 ID 并且完全分离,即使您从作业接收数据,数据也是“反序列化”的,这意味着它不是真实对象,只是它的副本。

    因此,如果您的目的是在 firefox 进程没有响应时停止作业,您可以像这样创建一个简单的作业:

    当进程响应时,当不响应时......

    $Job = Start-Job {
    
    ## Monitor the job and wait until it stop responding...
    while ((Get-Process firefox).Responding) {sleep -Milliseconds 100}
    
    ## do whatever you want, when it stopped responding...
    if (!(Get-Process firefox).Responding) {
        Stop-Process firefox
        Start-Process firefox
        }
    }
    

    【讨论】:

    • 该脚本的目的是在进程无响应时重启进程,读取服务器数据并截图。因为我想观看多个进程,所以我认为最好为每个被观看的进程设置一个后台作业。我还选择了一个后台作业,因为我想创建一个 Windows 窗体或一个通知图标来可视化脚本正在运行。当我不在后台作业中进行处理时,我的 Windows 窗体不会响应任何内容。如果我在后台作业中执行读取、屏幕截图和重新启动部分,它也不起作用。
    • 不,不完全是。如果我像while (!(Get-Process firefox).Responding) {#do stuff} 这样执行作业,它会在开始后立即完成作业,因为它不监视作业。我的代码的while (1) 进行此监控。你的工作只检查一次属性,如果进程没有响应,它会执行脚本块,直到进程再次启动。 while (1) 的问题是,如果脚本块被执行,它不会给你任何信息。这就是为什么我尝试在循环中执行stop-job,所以当工作状态“停止”时我可以做一些事情
    • 不,它检查响应属性是否为真,所以它会休眠 100 毫秒,然后它会检查该属性是否为真,不执行脚本块,因为该属性是真实,并完成工作。所以我想while (1) 是必要的。我尝试将breakreturn 移出while loop,但没有成功。
    • 第一个 while 将继续休眠,直到进程没有响应,这意味着作业将继续运行...对于测试,您可以启动记事本并运行:$Job = start-job {while ((Get-Process notepad).Responding) {sleep 1}} 然后执行@987654331 @你会看到作业仍在运行
    • 如果我在 powershell ISE 中尝试这个确切的代码,它会在启动后立即完成工作。编辑:好的,我错了。有用。它对我不起作用,因为我没有将它分配给变量。非常感谢您的努力!
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多