为什么这个简单的Powershell脚本在需要时不退出?

时间:2019-06-28 18:21:53

标签: windows powershell

我有一个衍生自from here的简单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}

如您所见,脚本应该在满足条件(执行“操作”)时退出,因为继续值更改为false,然后循环应该结束并且脚本应该退出。但是,它一直在继续。即使满足条件,循环也是无止境的。

我也尝试使用exit to exit out of the powershell script。也不起作用。我尝试删除sleep 1,但是由于无限循环而没有任何时间间隔,最终导致我的CPU被杀死。

如何满足文件更改条件将其退出?

1 个答案:

答案 0 :(得分:3)

您的$action事件处理程序脚本块不在与脚本 [1] 相同的范围内运行,因此您的脚本永远不会看到您设置的$continue变量在脚本块中。

作为解决方法,您可以:

  • 在脚本中初始化名为$continue global 变量:$global:continue = $true

  • 然后在事件处理程序脚本块中设置该变量:$global:continue = $false

  • ,然后在脚本循环中检查全局变量的值:while ($global:continue) {sleep 1}

  • 请确保在退出脚本之前删除全局变量,否则它会在会话中徘徊:Remove-Variable -Scope Global count

    • 通常,正如Theo所建议的那样,一旦完成观看,请确保正确处置System.IO.FileSystemWatcher实例:$watcher.Dispose()

[1]它在同一会话中运行,但是在dynamic module内部。