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



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

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

我正在使用Powershell的第5版.exe

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

FileSytemWatcher正在为我工作,但它不可靠。专家请提出任何建议。

PS:从捕获块打印没有错误

$FileSystemWatcher = new-object system.io.FileSystemWatcher
$FileSystemWatcher.path="\networklocationfolder"
$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()
}


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

无论哪种方式,在编写了几个自定义函数来替换LogWrite和SendEmail之后,代码似乎都可以正常工作。一些问题和建议可以解决问题的根源:

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

法典

$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = "\networklocationfolder"
$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()
}

编辑: RE: user1386121 7/10/20

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

function Initialize-FileSystemWatcher {
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = "\networklocationfolder"
$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($_)
} 

引用

  • https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.internalbuffersize?view=netcore-3.1
  • https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netcore-3.1

最新更新