如果语句

时间:2019-01-15 20:30:57

标签: arrays powershell if-statement do-while jobs

我最近开始创建包含GUI的Powershell脚本。
为了防止GUI冻结,我创建了一个后台作业,其中运行了我的函数“ xyz” ...
我想捕获一个特定的窗口标题。如果此窗口关闭,则应触发if。

现在,这个脚本的问题如下:
如果我运行脚本时未将其放在后台作业中,则会注意到if语句并返回我想要的值。

如果我运行脚本并将任务放入后台作业,则该作业不会停止并且不会识别if语句。
有人可以解决这个问题吗?

Function xyz {
    $global:TitleArray = @("Termius - Hosts","Some Window Title","...")
    $global:WindowClosed = $false
    $global:TitleArray | Out-Host
    $global:Job = start-job -Name FindGame {
        Do {
            (Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle) | % {
                if($_.MainWindowTitle -in $global:TitleArray){
                    $global:WindowFound = $true
                    $global:FoundWindowName = $_.MainWindowTitle
                    do {
                        $WindowArray = @()
                        (Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle) | % {
                           $WindowArray += $_.MainWindowTitle
                        }
                        if($global:FoundWindowName -notin $WindowArray){
                            $global:WindowClosed = $true
                        }
                         Sleep 1
                    } while ($global:WindowClosed -ne $true)
                }

                if($global:WindowClosed){
                    $Global:FoundWindowName | Out-Host
                    exit
                }
                Sleep 1
            }         
        } while ($true)
    }
}

xyz

1 个答案:

答案 0 :(得分:5)

PowerShell作业(类型为PSJob)在单独的进程中运行,因此它们无法访问调用程序环境,甚至无法访问Global范围内的变量。

要获取有关作业的信息,应在作业的脚本块中定义一个param()块,然后使用-ArgumentList的{​​{1}}参数发送值。请注意,这是的一次传递。

要从作业中返回数据,只需像往常一样通过管道将其发送出去,然后访问数据就需要使用Start-Job来确定作业是否“具有附加数据”,以及是否确实如此,您可以使用Get-Job来检索该数据。

不幸的是,这一切意味着您仍然需要主线程来管理后台作业,从而无法达到目的。

您可以look into Register-ObjectEvent instead,并将其与可能引发事件的某种.Net对象配对。这些似乎确实可以在进程中运行,但除此之外,它们还可以基于您可能真正感兴趣的事件而触发,而无需管理循环。

因此,最简单的方法也许只是为了结识,您可以look at a timer example where a timer object fires the event on an interval:

Receive-Job

但是Microsoft页面上的示例甚至包括监视来自WMI的流程创建事件,因此和/或流程退出事件(?)可能值得研究。