Powershell FileSystemWatcher 在一段时间后停止通知

Powershell FileSystemWatcher stops notifications after some time

我有一个简单的 powerscript,它监视一个文件夹以添加新文件。该脚本正在监视根文件夹。此根文件夹有多个子文件夹。用户可以将文件复制到这些子文件夹中的任何一个,脚本将向用户发送通知,说明文件已到达。

这里的问题是 - 当脚本从命令行参数启动时,它会工作一段时间。当有新文件复制到根文件夹中的任何文件夹时,它会发送通知。但是电子邮件通知并不一致。它会在几分钟后自动停止发送通知,即使文件夹中有新文件。

我正在使用 Powershell.exe

的第 5 版

脚本没有错误。脚本仍将状态显示为 运行,但通知停止。

FileSytemWatcher 正在为我工​​作,但它不可靠。请专家们提点建议。

PS: Catch 块没有打印错误

$FileSystemWatcher = new-object system.io.FileSystemWatcher
$FileSystemWatcher.path="\networklocation\folder"
$FileSystemWatcher.Includesubdirectoriesncludesubdirectories=$true
$FileSystemWatcher.EnableRaisingEventsnableraisingevents=$true

$action={
   try
    {
        $detail=$event.SourceEventArgs
        $FullPath=$details.FullPath
        $ChangeType=$details.ChangeType
        $FileName=$event.SourceEventArgs.Name
        $EmailBody="Something has arrived"
        
        switch($ChangeType)
        {
            'Created' { "CREATED"
                        SendEmail $fromEmailID $usereEmailID $cc $Subject $EMailBody
                        Start-Sleep -Seconds 1
                      }
        }
    }
    catch
    {
        Logwrite($_)
        Write-Host "An error has occured"
        Write-Host $_
    }
    }
    
$handlers = .{
                Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
                }

try
{
    do
        {
            Wait-Event -Timeout 1
        }while ($true)
            
}       
catch
    {
        Logwrite($_)
    }
finally
    {
        LogWrite('Finally')
        Unregister-Event -SourceIdentifier FSCreate
        $handers |
        Remove-Job
        $FileSystemWatcher.EnableRaisingEvents=$false
        $FileSystemWatcher.Dispose()
    }
    
    

好吧,就像评论中提到的那样,您的代码中有一些错别字……这些使得 运行 无法实现。我还稍微清理了语法。我不确定这些只是您在此处粘贴代码时遇到的问题还是什么...我在下面包含了清理后的代码(注意: I由于我自己对函数的迭代,确实更改了传递给 SendEmail 的参数的顺序)

不管怎样,在编写了几个自定义函数来替换 LogWrite 和 SendEmail 之后,代码似乎工作正常。一些问题和建议可以帮助您找到问题的根源:

  1. 你运行在干什么OS? Windows.
  2. 的不同迭代施加了某些限制
  3. 你运行怎么样? (即计划任务,来自 PowerShell 终端、ISE 等...)
  4. 是否存在任何类型的网络限制,将您的外发邮件视为某种威胁并阻止它?也许 SendMail 功能也可以记录到文件中。
  5. 据我了解,FSW 存在一些限制,包括 InternalBufferSize 可能会溢出,从而导致问题。根据 Microsoft(请参阅下面的参考资料)“您可以为 InternalBufferSize 属性 设置的最大大小,用于监视网络上的目录。" 也许 重置 观察者每 X 个事件使用内置迭代器将是遏制此问题的公平折衷。

代码

$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = "\networklocation\folder"
$FileSystemWatcher.IncludeSubDirectories = $true
$FileSystemWatcher.EnableRaisingEvents = $true

$action = {
    try {
        $detail = $event.SourceEventArgs
        $FullPath = $detail.FullPath
        $ChangeType = $detail.ChangeType
        $FileName = $event.SourceEventArgs.Name
        $EmailBody = "$FileName has arrived"
        $Subject = 'A File Has Arrived!'
        
        $Message = "$FileName has arrived"
        LogWrite($Message)
        
        switch ($ChangeType) {
            'Created' {
                "CREATED"
                SendEmail $userEmailID $Subject $EMailBody $fromEmailID #$cc
                Start-Sleep -Seconds 1
            }
        }
    } catch {
        Logwrite($_)
        Write-Host "An error has occured"
        Write-Host $_
    }
}
    
$handlers = . {
    Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
}

try {
    do {
        Wait-Event -Timeout 1
    }while ($true)
} catch {
    Logwrite($_)
} finally {
    LogWrite('Enter Finally')
    Unregister-Event -SourceIdentifier FSCreate
    $handers | Remove-Job
    $FileSystemWatcher.EnableRaisingEvents = $false
    $FileSystemWatcher.Dispose()
}

编辑:回复:user1386121 7/10/20

以下代码是使用内置迭代器每 X 次事件重置文件系统观察程序的示例。

function Initialize-FileSystemWatcher {
    $FileSystemWatcher = New-Object System.IO.FileSystemWatcher
    $FileSystemWatcher.Path = "\networklocation\folder"
    $FileSystemWatcher.IncludeSubDirectories = $true
    $FileSystemWatcher.EnableRaisingEvents = $true

    $action = {
        try {
            $detail = $event.SourceEventArgs
            $FullPath = $detail.FullPath
            $ChangeType = $detail.ChangeType
            $FileName = $event.SourceEventArgs.Name
            $EmailBody = "$FileName has arrived"
            $Subject = 'A File Has Arrived!'
        
            $Message = "$FileName has arrived"
            LogWrite($Message)
        
            switch ($ChangeType) {
                'Created' {
                    "CREATED"
                    SendEmail $userEmailID $Subject $EMailBody $fromEmailID #$cc
                    Start-Sleep -Seconds 1
                }
            }
        } catch {
            Logwrite($_)
            Write-Host "An error has occured"
            Write-Host $_
        }
    }
    
    $handlers = . {
        Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
    }
    @{
        Watcher = $FileSystemWatcher
        Handler = $handlers
    }
}

try {
    LogWrite('Enter Try...')
    $MaxEvents = 5
    while ($true) {
        Write-Host 'New Watcher!'
        $IFSW = Initialize-FileSystemWatcher
        while ($IFSW.Handler.Output.Count -le $MaxEvents) {
            Wait-Event -Timeout 1
        }
        LogWrite('Cleaning Up FileSystemWatcher')
        Unregister-Event -SourceIdentifier FSCreate
        $IFSW.Watcher.EnableRaisingEvents = $false
        $IFSW.Watcher.Dispose()
        $IFSW.Handler.Dispose()
        $IFSW = $null
    }
} catch {
    Logwrite($_)
} 

参考资料