gpt4 book ai didi

powershell - System.IO.FileSystemWatcher 只在编辑过的文件上通知一次

转载 作者:行者123 更新时间:2023-12-04 14:38:30 30 4
gpt4 key购买 nike

该脚本使用文件系统观察程序来监视蜜 jar 文件夹,并报告任何更改(编辑、重命名、删除或创建),然后执行一些操作。

这些操作在创建、重命名和删除时工作正常。

但是在编辑时,我只能让脚本触发一次 Action 。因此,例如,如果测试设备尝试编辑蜜 jar 文件夹中的文件,则会触发操作。但是如果同一台设备试图再次编辑同一个文件或不同的文件,编辑的观察者似乎不起作用,因为没有触发 Action 。

所以我尝试通过任务调度程序每 5 分钟重置一次脚本(每 5 分钟启动一次脚本),但结果仍然相同。

这是代码:

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "\\vmserver2\_Do_Not_Delete_Or_Rename"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType

$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline

$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }

$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername

Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}

### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Deleted" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}

我对 powershell 很陌生,所以我不明白其余事件的观察者何时工作,而只有编辑不起作用。

最佳答案

你的核心逻辑是合理的。

如果您将操作块简化为仅执行写入主机部分,则它应该始终有效。
我相信您的问题是在第二次调用时,您会收到一个您没有捕获的终止错误,作为返回,它会阻止事件触发。

尝试用以下内容替换您的 ActionScript 块

$action = {
try {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType

$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline

$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }

$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername

Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}
catch {
Write-Host 'an error was thrown :(... Fortunately, it was caught.'
}
}

这应该可以纠正您的更改事件仅触发一次的问题。

这是一个使用 3 个观察者检查同一目录上的文件更改的示例。
您会注意到,当计数器达到 5 后,3 个观察者中只有 2 个继续正常工作。不产生任何错误的那个 watcherNoError以及产生终止错误但被 Try catch 捕获的错误 watcherErrorsTryCatch .
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$PathToWatch = "\\127.0.0.1\c$\_"

$watcherNoError = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}
$watcherWithErrors = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}
$watcherErrorsTryCatch = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}

$Global:Counter = @{
watcherNoError = 0
watcherWithErrors = 0
watcherErrorsTryCatch = 0
}
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {

$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType



Switch ($Event.MessageData.Name) {
"NoErrors" {
$Global:Counter.watcherNoError +=1
$count = $Global:Counter.watcherNoError
}
"WithErrors" {
$Global:Counter.watcherWithErrors +=1
$count = $Global:Counter.watcherWithErrors
if ($count -eq 5) {
Write-Host 'A terminated errow will be thrown...' -ForegroundColor DarkMagenta
Throw 'oh no !'
}

}
"WithErrorsTryCatch" {
$Global:Counter.watcherErrorsTryCatch +=1
$count = $Global:Counter.watcherErrorsTryCatch
if ($count -eq 5) {
try {
Throw 'oh no !'
}
catch {
Write-Host 'error was caught... You are safe ;)' -ForegroundColor Green
}
}

}
}

$logline = "Count: $Count - $($event.MessageData.Name): $changeType, $path"
write-host $logline -ForegroundColor $Event.MessageData.ForegroundColor


}

### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcherNoError "Changed" -Action $action -MessageData @{Name='NoErrors';ForegroundColor='Yellow'}
Register-ObjectEvent $watcherWithErrors "Changed" -Action $action -MessageData @{Name='WithErrors';ForegroundColor='DarkMagenta'}
Register-ObjectEvent $watcherErrorsTryCatch "Changed" -Action $action -MessageData @{Name='WithErrorsTryCatch';ForegroundColor='Green'}

while ($true) {sleep 5}




$action = {
try {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType

$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline

$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }

$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername

Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}
catch {
Write-Host 'an error was thrown :(... Fortunately, it was caught.'
}
}

VSCode output of previous sample

附加说明:
即使它不是您问题的解决方案,您仍然应该在该 Action 脚本块中放置一个 try/catch,因为终止错误将停止对下一个更改的进一步处理。

关于powershell - System.IO.FileSystemWatcher 只在编辑过的文件上通知一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51223887/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com