Register-ObjectEvent cmdlet 在 Powershell 上无法正常工作,但在 ISE 上工作

2023-12-04

我正在开发一个 Powershell 脚本来监视文件夹,当创建新项目时,脚本需要将该文件复制到另一个文件夹。

我遇到的问题是,当我在 Powershell ISE 中执行它时,它工作得很好,但是当我在 Powershell 上执行它时,它仅在 Powershell 窗口打开的时间段内工作(> 1 秒)。

我尝试将 sleep 命令放在最后,发现只有当脚本结束时才会执行操作,在这种情况下,当我在 Powershell 中按 CTRL+C 停止脚本时,应该执行的操作创建的项目全部一起执行。

不知道我是否做错了什么或者只是误解了什么。

这是我用来测试它的脚本:

$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.path = "\\192.168.5.127\data\TestWatcher"
$Destination = "C:\TestWatcher"
$Watcher | Get-Member -MemberType Event
$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-ObjectEvent $Watcher 'Created' -Action $action

任何帮助或建议将不胜感激。

此致,


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.
    • See GitHub 问题 #11705.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Register-ObjectEvent cmdlet 在 Powershell 上无法正常工作,但在 ISE 上工作 的相关文章

随机推荐

  • CSS3 替代 jQuery.fadeIn 和 fadeOut

    我编写了少量代码来尝试复制 jQuery fadeIn and fadeOut 使用 CSS 过渡的函数在触摸设备上看起来更好 理想情况下 我希望避免使用库 以便我可以准确地编写我想要的内容 并将其作为学习练习 fadeOut效果很好 的想
  • 是否有相当于“shopt -s nullglob”的 ZSH?

    我目前正在编写一个脚本 该脚本可以从我的桌面上删除所有 PNG 文件 我想创建一个文件路径数组 然后使用rm对每一个都发出命令 这是相关的代码 usr bin env bash shopt s nullglob files HOME Des
  • 搜索长字符串的 SQL 性能

    我需要将用户代理字符串存储在数据库中 以跟踪和比较不同浏览器之间的客户行为和销售业绩 一个非常简单的用户代理字符串大约有 100 个字符长 决定使用一个varchar 1024 用于在数据库中保存用户代理数据 我知道这有点矫枉过正 但这就是
  • 如何使用存储过程在 SQL Server 中透视表?

    原始输出 期望的输出 检查下面的示例供您参考 或者发布您当前的输出和所需的输出 SELECT INTO tblStock FROM SELECT A PartCode 10 StockQty WHs A Location UNION ALL
  • 使用vbs打开excel工作簿,运行宏并保存工作簿

    我有一个宏 需要每 5 分钟运行一次 我有一个vbs安排宏的文件 该宏正在检查某个文件夹中的新文件 将其信息写入表中 然后将文件移动到存档中 该表与宏位于同一个 Excel 文件中 它运行宏正常 但最后 它询问我是否要保存文件 我需要它来自
  • 使用多列的列表理解

    我有一个 pandas 数据框 其中有一列用于实际值和预测值 我想使用列表理解创建一个新列 当实际值 预测时 该列 1 否则为 0 我知道如何使用 np where 来做到这一点 但我很好奇如何使用列表理解来做到这一点 这可以使用np wh
  • 我可以在保存之前检查下载的图像是否损坏吗?

    在将下载的图像保存到我的文档目录之前 我可以检查它是否已损坏吗 如果是的话请告诉我怎么做 谢谢 UIImage im UIImage alloc initWithData YourNSData UIImageView imview test
  • 在 C# 中,有没有一种方法可以使用反射仅检索内置数据类型属性

    使用反射我想只检索内置数据类型来自 C 对象的属性 有没有比使用一堆更好的方法来做到这一点 或 在一个Where指定我感兴趣的类型的方法 Type sourceType typeof TSource var props sourceType
  • PDFbox 说 PDDocument 已关闭,但未关闭

    我正在尝试使用 PDFbox 填充重复的表单 我正在使用 TreeMap 并用单独的记录填充表单 pdf 表单的格式是这样的 第一页列出六条记录 第二页插入一个静态页面 对于大于 6 个记录的 TreeMap 重复该过程 我得到的错误特定于
  • 在反引号中使用管道

    我尝试使用管道运行命令但收到错误 echo abc echo grep a grep b grep No such file or directory grep grep No such file or directory grep b N
  • 从sqlite数据库读取信息,语法?如何在 html5 webapp 中使用它?

    我正在构建一个 Web 应用程序 并且刚刚开始使用 SQLite 我已经能够创建我的表单 打开我创建的数据库 创建表和我需要的字段 然后将数据输入到字段中 现在 我尝试使用 SELECT 语句读回数据 将其显示在屏幕上并作为列列表 我只是不
  • 我的 Android 应用程序在调试中显示谷歌地图,但在发布到市场时不显示

    我创建了一个使用 Google 地图和 Google Playstore 的应用程序 并使用 Eclipse 和 Android SDK 进行调试 地图显示在我正在运行的设备上 但发 布时它不会显示在应用程序上 只有一个大的灰色屏幕 And
  • 将 IPTC 数据写入文件

    我需要获取一个现有的 jpg 文件并修改其 IPTC 条目中的标题 描述和关键字 这里有几个与此相关的主题 但所有主题要么没有答案 要么只有部分答案 我已经知道如何阅读 IPTC 信息 但需要编辑它们 有人可以阐明这个经过大量研究且鲜为人知
  • 用Scheme语言计算浮点变量

    我想在 Ansys Fluent 中读取多个数据文件 总共 10 个 我写了一个使用方案语言的日志文件 Do count 11 100 count 0 100 gt count 12 000 ti menu load string form
  • 在脚本中创建 sudo 用户,不提示输入密码,更改为用户而不中断脚本

    这就是我试图在脚本中做的事情 它在这里手动工作 但提示我输入密码 我如何能 创建一个新用户 使用 sudo privs 切换到该用户 继续执行脚本的其余部分 sudo adduser centos sudo passwd centos us
  • 新线程,应用程序在阶段关闭后仍在运行

    所以我遵循了这个教程 https www youtube com watch v gyyj57O0FVI 我在 javafx8 中编写了完全相同的代码 public class CountdownController implements
  • 如何睡眠直到特定时间 YYYY-MM-DD HH:MM:SS?

    我一直在考虑做一个睡眠函数 让它休眠直到调用某个日期 我的想法是基于日期 例如 2019 01 20 12 00 00 我还没有真正弄清楚如何开始解决这个问题 我的想法是类似的东西 if there is a date given time
  • 如何在 Android 中播放 YouTube 视频?

    我有一个VideoView我设置了 youtube 视频的 URI 并设置android permission INTERNET但当我想播放视频时收到此消息 你无法播放视频 这个视频播放器的代码片段 mVideoView VideoView
  • ASP.NET 的调度程序?

    我想每天晚上在某种任务或调度程序中运行一些应用程序代码 框架中有内置功能吗 如果没有 有什么简单的第三方框架来进行调度 Thanks 您可以创建控制台应用程序并将其作为计划任务运行 或者 您可以考虑使用 Quartz Net 它是 Java
  • Register-ObjectEvent cmdlet 在 Powershell 上无法正常工作,但在 ISE 上工作

    我正在开发一个 Powershell 脚本来监视文件夹 当创建新项目时 脚本需要将该文件复制到另一个文件夹 我遇到的问题是 当我在 Powershell ISE 中执行它时 它工作得很好 但是当我在 Powershell 上执行它时 它仅在