PowerShell中的一个已知问题是FileSystemWatcher在事件上触发两次。我正在尝试解决此问题,因为我正在查看正在创建的文件,然后将其推送到打印机。两次触发意味着我得到了重复的打印输出
我知道之前曾有人问过这个问题,但是当我谈到Powershell时(对于一般的脚本来说)我是一个新手,所以有些答案直指我了
在代码中,我正在监视一个文件夹,然后将子目录名称作为发送作业的打印机名称传递。这是因为使用的软件正在将pdf文件从远程位置复制到这些文件夹中(由于citrix,该软件无法直接访问打印机)
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "L:\Label\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = { $path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$printer = Split-Path (Split-Path $path -Parent) -Leaf
$logline = "$(Get-Date), $changeType, $path, $printer"
Add-content "c:\prog\log.txt" -value $logline
C:\prog\SumatraPDF.exe -print-to "\\http://srv:631\$printer" $path
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {sleep 5}
我希望仅在将pdf文件放入监视文件夹时看到打印命令(苏门答腊呼叫)仅发生一次
答案 0 :(得分:0)
我认为FileSystemWatcher在事件(而不是在何处获得该信息)上触发两次不是已知问题。
无论如何,如果我还是我自己,都不会在Powershell中编写FileSystemWather事件的代码,这确实很痛苦。
相反,您可以使用Powershell Guard,只需传递print命令而不是TestCommand。 https://github.com/smurawski/PowerShellGuard
PowerGuard所做的只是抽象使用FileSystemWatcher。您可以在Powershell脚本中创建打印命令,只需让PowerGuard使用-TestCommand“ Print.ps1。\ PathToYourFile”来调用脚本
最终解决方案(由发布者本人完成):
dir \\srv\label\prnlblCuts\*.pdf | New-Guard -TestCommand "C:\PROG\SumatraPDF.exe -print-to \\srv-tsv:631\prnlblCuts" -TestPath "$($_.FullName)" -Wait
答案 1 :(得分:0)
这里不是告诉您应该做什么或不应该做什么,而是按照您的要求去做:
sfml
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$global:canDoEvent = $True #NEW
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "L:\Label\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$action = { if ($global:canDoEvent) { #NEW
$global:canDoEvent = $False #NEW
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$printer = Split-Path (Split-Path $path -Parent) -Leaf
$logline = "$(Get-Date), $changeType, $path, $printer"
Add-content "c:\prog\log.txt" -value $logline
C:\prog\SumatraPDF.exe -print-to "\\http://srv:631\$printer" $path
}
}
它可能需要调整,我不是专家,但这就是想法。
基本上,添加一个全局布尔值 var = True,将您的等待事件置于 do-while 循环内的超时状态,在每个循环中将变量设为真,然后在您的事件操作中将其设为假。您的超时将定义事件触发的频率。一秒钟就足以防止多次触发事件。显然,如果存在可以在同一秒内创建和打印 1 个以上唯一文件的上下文,它会跳过它们。