Gregor y在评论中提供了关键提示:
To 确保您的脚本无限期地继续处理事件, 你可以use a Wait-Event在脚本末尾调用无限期地等待永远不会到来的事件,这会让你的脚本保持运行,但是 - 不像Start-Sleep
- does not通过传递给的脚本块块处理事件Register-ObjectEvent's -Action
范围:
$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.path = "\\192.168.5.127\data\TestWatcher"
$Destination = "C:\TestWatcher"
$Watcher.EnableRaisingEvents = $true
$action = {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$changetype = $event.SourceEventArgs.ChangeType
Write-Host "File $name at path $path was $changetype at $(get-date)"
Copy-Item $Watcher.path $Destination
}
# Register the event with a self-chosen name passed to -SourceIdentifier
# and an -Action script block.
$eventJob =
Register-ObjectEvent $Watcher Created -SourceIdentifier FileWatcher -Action $action
# Now wait indefinitely for an event with the same source identifier to arrive.
# NONE will ever arrive, because the events are handled via the -Action script block.
# However, the call will prevent your script from exiting, without
# blocking the processing of events in the -Action script block.
# Use Ctrl-C to exit the script; the `finally` clause ensures cleanup.
try {
Wait-Event -SourceIdentifier FileWatcher
}
finally {
# Clean up: Remove the event job, which also unregisters the event.
$eventJob | Remove-Job -Force
}
或者,凑合一下without an -Action
脚本块和进程事件Wait-Event
loop:
$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.path = "\\192.168.5.127\data\TestWatcher"
$Destination = "C:\TestWatcher"
$Watcher.EnableRaisingEvents = $true
# Register the event with a self-chosen name passed to -SourceIdentifier
# but WITHOUT an -Action script block.
Register-ObjectEvent $Watcher 'Created' -SourceIdentifier FileWatcher
# Now use Wait-Event with the chosen source identifier to
# to indefinitely receive and then process the events as they
# become available.
try {
while ($event = Wait-Event -SourceIdentifier FileWatcher) {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$changetype = $event.SourceEventArgs.ChangeType
Write-Host "File $name at path $path was $changetype at $(Get-Date)"
Copy-Item $Watcher.path $Destination
$event | Remove-Event # Note: Events must be manually removed.
}
}
finally {
# Clean up.
Unregister-Event -SourceIdentifier FileWatcher
}
替代方案事件轮询循环允许前台活动:
您可以调整以上内容以使用polling方法,通过使用无条件的无限循环,并替换Wait-Event
with a Get-Event在循环体内调用,然后是短睡眠间隔(通过Start-Sleep),它允许您执行前台活动当没有收到任何事件时:
$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.path = "\\192.168.5.127\data\TestWatcher"
$Destination = "C:\TestWatcher"
$Watcher.EnableRaisingEvents = $true
# Register the event with a self-chosen name passed to -SourceIdentifier
# but WITHOUT an -Action script block.
Register-ObjectEvent $Watcher 'Created' -SourceIdentifier FileWatcher
# Now enter an infinite loop that uses Get-Event to poll for
# available events and processes them.
# If none are available, foreground activity can be performed
# (which should be short-lived, otherwise event retrieval is blocked).
try {
while ($true) {
if ($event = Get-Event | Where-Object SourceIdentifier -eq FileWatcher) {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$changetype = $event.SourceEventArgs.ChangeType
Write-Host "File $name at path $path was $changetype at $(Get-Date)"
Copy-Item $Watcher.path $Destination
$event | Remove-Event # Note: Events must be manually removed.
} else { # No event available.
# Perform (short-lived) foreground activities here.
Write-Host -NoNewline .
Start-Sleep -Milliseconds 500 # Sleep a little, to avoid a tight loop.
}
}
}
finally {
# Clean up.
Unregister-Event -SourceIdentifier FileWatcher
}
Note:
- Due to a bug present up to at least PowerShell v7.3.x,
Get-Event
doesn't work with the -SourceIdentifier
parameter, hence the Get-Event | Where-Object SourceIdentifier -eq FileWatcher
workaround above.