【问题标题】:While inside of onCreated gets stuck on a array in PowerShell but works fine in ISE虽然 onCreated 内部卡在 PowerShell 中的数组上,但在 ISE 中工作正常
【发布时间】:2018-01-18 13:56:32
【问题描述】:

编写了一个脚本来监视文件夹中的新文件。当 onCreated 被调用时,它会增加到我列表中的下一个驱动器号,然后检查该驱动器的可用空间。如果可用空间在我的要求之下,它会再次增加。我的完整脚本在 ISE 中运行良好。

这是一个简化版本,我仍然无法开始工作。 当在 PowerShell 中运行时,它卡在$DriveVar 上并且只输出“marker1”。如果您在 ISE 中运行,marker2 行会正确旋转您复制到文件夹中的每个文件的驱动器号。

$filter = '*.*'
$Watchfolder = "C:\Script\watch"
$LocationArray = "L","J","K","Q","S"
$LocationCount = [int]$LocationArray.Count
$LastUsed = [int]0

$Watcher = New-Object IO.FileSystemWatcher $Watchfolder, $filter -Property @{
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite' }

$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier FileCreated -Action {
    $Freespace = [long]-1
    while ($Freespace -le 0) {
        $LastUsed++
        if ($LastUsed -ge $LocationCount) {
            $LastUsed = 0 }
        Write-Host "marker1"

        $DriveVar = $LocationArray[$LastUsed]
        Write-Host "marker2 $DriveVar"
        $Freespace = 5
    }
}

PowerShell 中的输出:

标记1

ISE 中的输出:

标记1 标记2 J 标记1 标记2 K 标记1 标记2 Q

我尝试为 $DriveVar 和其他一些东西(都在 ISE 中工作)调用一个函数,但我似乎无法让它工作。如果我自己使用 while 循环(没有 onCreated),它在 Powershell 中可以正常工作。

【问题讨论】:

  • 如果关闭 ISE,然后重新启动并运行脚本,它在 ISE 中是否仍能正常工作?如果是这样,这可能是 STA 与 MTA 的问题,我们或许可以解决这个问题。
  • “如果关闭 ISE,然后重新启动并运行脚本,它在 ISE 中是否仍然可以正常工作”刚刚测试过,是的。
  • 尝试使用-Mta参数启动powershell.exe,看看你的脚本在这样运行时是否仍然挂起。
  • 我尝试了 -Mta 和 -Sta(不确定默认是什么)仍然挂在同一个位置。
  • 这在 2012R2 / PS4.0 上,但也在 Win7 / PS3.0 上测试,结果相同。

标签: powershell while-loop file-watcher


【解决方案1】:

看起来这是一个范围问题。我用你的代码做了一些测试,得到了相同的结果。我能够通过将变量范围限定为$global: 来解决问题,然后得到了预期的结果。试试这个:

$filter = '*.*'
$Watchfolder = "C:\Script\watch"
$global:LocationArray = "L","J","K","Q","S"
$global:LocationCount = [int]$LocationArray.Count
$global:LastUsed = [int]0

$Watcher = New-Object IO.FileSystemWatcher $Watchfolder, $filter -Property @{
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite' }

$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier FileCreated -Action {
    $Freespace = [long]-1
    while ($Freespace -le 0) {
        $global:LastUsed++
        if ($global:LastUsed -ge $global:LocationCount) {
            $global:LastUsed = 0 }
        Write-Host "marker1"

        $DriveVar = $global:LocationArray[$global:LastUsed]
        Write-Host "marker2 $DriveVar"
        $Freespace = 5
    }
}

我只是在你的Write-Host "marker1" 行之后尝试Write-Host $LocationArray 发现了这个,它只是吐出一个空行。

【讨论】:

  • 非常感谢您修复了它!现在还有其他东西挂断了我的完整脚本,但我确定我只需要让其他一些全球化。
【解决方案2】:

我们知道全局变量不受欢迎,但对于您的用例,将您的驱动器、计数、lastused 设置为全局变量,如下所示。

$filter = '*.*'
$Watchfolder = "D:\Scripts\watch"

$Global:LocationArray = "L","J","K","Q","S"
$Global:LocationCount = [int]$LocationArray.Count
$Global:LastUsed = [int]0

$Watcher = New-Object IO.FileSystemWatcher $Watchfolder, $filter -Property @{
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite' }

# Clear previous event
Unregister-Event -SourceIdentifier FileCreated -ErrorAction SilentlyContinue -Force

$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier FileCreated -Action {
    $Freespace = [long]-1
    while ($Freespace -le 0) {
        $LastUsed++
        if ($LastUsed -ge $LocationCount) 
        { $LastUsed = 0 }
        Write-Host "marker1"

        $DriveVar = $LocationArray[$LastUsed]
        Write-Host "marker2 $DriveVar"
        $Freespace = 5
    }
}

...在 ISE 中

 marker1
marker2 J
marker1
marker2 K
marker1
marker2 Q

...在控制台主机中

 marker1
marker2 J
marker1
marker2 K
marker1
marker2 Q

【讨论】:

    猜你喜欢
    • 2014-06-16
    • 1970-01-01
    • 2014-12-11
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多