Массив Powershell-notin не сработает, если - PullRequest
0 голосов
/ 15 января 2019

Я недавно начал создавать скрипт powershell, включая графический интерфейс.
Чтобы предотвратить зависание графического интерфейса, я создал фоновое задание, в котором моя функция "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 голосов
/ 15 января 2019

Задания PowerShell (типа PSJob) выполняются в отдельном процессе, поэтому они не имеют никакого доступа к среде вызывающей программы, даже к переменным в глобальной области.

Чтобы получить информацию в задании, вы должны определить блок param() в блоке сценария задания, а затем использовать параметр -ArgumentList Start-Job для отправки значений. Обратите внимание, что это будет однократная передача значений .

Чтобы вернуть данные из задания, вы просто отправляете их по конвейеру, как обычно, и для доступа к данным вам нужно будет использовать Get-Job, чтобы определить, есть ли у задания "дополнительные данные", и если это так, вы используете Receive-Job для извлечения этих данных.

К сожалению, все это означает, что вам все еще нужен ваш основной поток для управления фоновым заданием, чтобы победить цель.

Вы можете посмотреть Register-ObjectEvent вместо и связать его с каким-то объектом .Net, который может вызывать события. Похоже, что они выполняются в процессе, но более того, они могут запускаться на основе событий, которые могут вас заинтересовать, без управления циклом.

Итак, в самом простом и, возможно, просто для ознакомления вы можете посмотреть на пример таймера, где объект таймера запускает событие с интервалом:

$timer = new-object timers.timer 

$action = {write-host "Timer Elapse Event: $(get-date -Format ‘HH:mm:ss’)"} 
$timer.Interval = 3000 #3 seconds  

Register-ObjectEvent -InputObject $timer -EventName elapsed –SourceIdentifier  thetimer -Action $action 

$timer.start()

#to stop run 
$timer.stop() 
#cleanup 
Unregister-Event thetimer

Но примеры на странице Microsoft даже включают мониторинг события создания процесса из WMI, так что и / или и событие выхода из процесса (?), Возможно, стоит посмотреть.

...