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 之后,代码似乎工作正常。一些问题和建议可以帮助您找到问题的根源:
- 你运行在干什么OS? Windows.
的不同迭代施加了某些限制
- 你运行怎么样? (即计划任务,来自 PowerShell 终端、ISE 等...)
- 是否存在任何类型的网络限制,将您的外发邮件视为某种威胁并阻止它?也许 SendMail 功能也可以记录到文件中。
- 据我了解,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($_)
}
参考资料
我有一个简单的 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 之后,代码似乎工作正常。一些问题和建议可以帮助您找到问题的根源:
- 你运行在干什么OS? Windows. 的不同迭代施加了某些限制
- 你运行怎么样? (即计划任务,来自 PowerShell 终端、ISE 等...)
- 是否存在任何类型的网络限制,将您的外发邮件视为某种威胁并阻止它?也许 SendMail 功能也可以记录到文件中。
- 据我了解,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($_)
}