【问题标题】:Why does this simple Powershell script not exit when needed?为什么这个简单的 Powershell 脚本在需要时不退出?
【发布时间】:2019-11-10 16:34:55
【问题描述】:

我有一个简单的 Powershell 脚本派生 from here,它应该在某个条件变为真时退出(文件删除、修改等)

脚本:

$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,然后循环应该结束并且脚本应该退出。然而,它仍在继续。即使满足条件,循环也是无限的。

我也尝试过使用exitto exit out of the powershell script。也不行。我尝试删除sleep 1,但是,由于没有任何时间间隔的无限循环,它最终杀死了我的cpu。

当文件更改条件满足时如何修复它退出?

【问题讨论】:

  • @Theo:链接的帖子是相关的,但不是重复的,因为 this 问题是关于使用事件处理程序中的变量将信息传达给主脚本。

标签: windows powershell


【解决方案1】:

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

作为一种解决方法,您可以:

  • 在你的脚本中初始化一个名为$continue全局变量:$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 内。

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 2021-05-12
    相关资源
    最近更新 更多