Почему этот простой скрипт Powershell не завершается при необходимости? - PullRequest
1 голос
/ 28 июня 2019

У меня есть простой скрипт Powershell, полученный отсюда , который должен завершиться, когда определенное условие становится истинным (файл удален, изменен и т. Д.)

Сценарий:

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users\me\Desktop\folder\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true  
$continue = $true

$action = { 
            Write-Host "Action..."
            $anexe = "C:\Users\me\Desktop\aprogram.exe"
            $params = "-d filename"
            Start $anexe $params
            $continue = $false
          }    

Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Deleted" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($continue) {sleep 1}

Как вы можете видеть, сценарий должен завершаться при выполнении условия (выполняется «действие»), поскольку значение continue изменяется на false, и цикл должен завершиться, а сценарий должен завершиться. Тем не менее, он продолжает идти. Цикл бесконечен даже при выполнении условия.

Я также пытался использовать exit для выхода из сценария powershell . Тоже не работает. Я попытался удалить sleep 1, но затем он убил мой процессор из-за бесконечного цикла без промежутка времени.

Как это исправить, чтобы выйти, когда условие изменения файла выполнено?

1 Ответ

3 голосов
/ 29 июня 2019

Ваш блок сценариев обработчика событий $action не работает в той же области, что и ваш сценарий [1] , поэтому ваш сценарий никогда не увидит переменную $continue, установленную в блоке сценария.

В качестве обходного пути вы можете:

  • инициализировать глобальную переменную с именем $continue в вашем скрипте: $global:continue = $true

  • затем установите эту переменную в своем блоке сценария обработчика событий: $global:continue = $false

  • и проверьте значение этой глобальной переменной в цикле вашего скрипта: while ($global:continue) {sleep 1}

  • обязательно удалите глобальную переменную перед выходом из скрипта, так как в противном случае она задержалась бы в сеансе: Remove-Variable -Scope Global count.

    • Кроме того, как правило, как разумно советует Тео , убедитесь, что правильно удалили экземпляр System.IO.FileSystemWatcher, как только вы закончите смотреть: $watcher.Dispose().

[1] Он работает в том же сеансе, но внутри динамического модуля .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...