我面前有一个任务的上下文:我想在 WinServer2012 上创建一个计划任务,该任务由文件的最后写入日期更改生成的事件触发。
我手中有 Powershell 代码(感谢https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b),它监视此类事件并回调特定操作,例如:
$folder = 'c:\temp' # Enter the root path you want to monitor.
$filter = 'test.txt' # You can enter a wildcard filter here.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore white
}
这段代码似乎创建了一种产生此类事件的机制,并注册了一个回调以响应此类事件。这是正确的理解吗?还是无论如何都会产生事件?当我查看 FileSystemWatcher 类的文档时,https: //msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx似乎没有文件更改通知此类的实例化。通知与事件不同吗?该类文档说它监视通知并引发事件。因此,除非实例化此类,否则这表明事件不存在。它表明通知与事件不同。
在任务计划程序实用程序中,我可以创建一个在事件上触发的任务,我可以使用 3 个字段:日志、源和事件 ID 来识别我想要触发的事件。仔细阅读日志选项,我发现与事件查看器实用程序中可用的事件日志变体有些相似之处。根据定义,所有事件是否都发送到特定日志?
我将如何确定可用的不同日志、源和事件 ID 以及它们所指的内容?任何文件?
Powershell 代码与我可以为任务计划程序中的触发器配置的内容之间是否存在联系?可能触发器不能做得那么具体,以至于无法监视单个文件的 LastWrite 更改,并且该任务会在各种文件系统事件上被过于频繁地调用。我手头的任务可能是最好的解决方案是在启动时运行 powershell 代码,但是,我真的在寻求对事件如何工作的更深入的了解。
谢谢你的帮助。
Chris Lewis - Microsoft Premier Support 提供了这个极好的答案:
嗨凯文,
我已将您的帖子包含在内,并以粗体字回答了内嵌的问题。如果您有任何其他问题或我所说的任何内容需要澄清,请告诉我:
这段代码似乎创建了一种产生此类事件的机制,并注册了一个回调以响应此类事件。这是正确的理解吗?还是无论如何都会产生事件?
来自 .NET 对象的委托调用在此上下文中引用的事件。这是一些关于此的一般文档:https ://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx 。如果没有任何委托订阅,则不会引发该事件。对象可能是一个 FileSystemWatcher,它是一个必不可少的包装类,它公开了 ReadDirectoryChanges 的大部分功能。它的使用有很多很多注意事项,它是一个尽力而为的监听器,因此必须预料到错过的事件。这是我过去写的几篇博客文章,讨论了它的局限性以及使用和不使用它的方法: https ://blogs.msdn.microsoft.com/winsdk/2015/05/19/filesystemwatcher-follies/ https://blogs.msdn.microsoft.com/winsdk/2015/06/04/filesystemwatcher-fencingpart-1/ https://blogs.msdn.microsoft.com/winsdk/2015/09/15/filesystemwatcher-fencingpart- 2/
当我查看 FileSystemWatcher 类的文档时,https: //msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx似乎没有文件更改通知此类的实例化。通知与事件不同吗?该类文档说它监视通知并引发事件。因此,除非实例化此类,否则这表明事件不存在。它表明通知与事件不同。
是的,通知和事件是不同的,在这个上下文中的事件仍然指的是与上面相同的东西。通知是指来自文件系统的数据,它向 ReadDirectoryChanges 的活动订阅者报告更改。如果没有人订阅或者内核很忙(对于这种特殊类型的 API 来说,这是最好的努力,这在 API 中是不常见的),将不会有任何通知。如果没有订阅者,甚至不会在内存中生成数据。此外,如果特定类型文件系统的驱动程序不支持该功能工作所需的 IOctl,则不会生成数据,但我目前知道的所有这些都支持。
在任务计划程序实用程序中,我可以创建一个在事件上触发的任务,我可以使用 3 个字段:日志、源和事件 ID 来确定我想要触发的事件。仔细阅读日志选项,我发现与事件查看器实用程序中可用的事件日志变体有些相似之处。根据定义,所有事件是否都发送到特定日志?
任务调度程序使用的事件查看器中的事件与 .NET 事件完全无关。不幸的是,为了跟踪对文件的更改,没有任何事件可以合理触发(您可以将更改日志记录到事件日志中,但是如果您触发了该事件,您会显着减慢系统速度,因为除非您有一个 NTFS 驱动器,除了您关心的一个文件之外几乎没有任何活动,否则将一直需要如此多的资源来监视和检查不同进程的更改)。您可以让代码一直运行以执行监视,然后在发生特定事件时写入特定事件,如果您这样做了,您可以触发任务调度程序运行该事件。
我将如何确定可用的不同日志、源和事件 ID 以及它们所指的内容?有这方面的文件吗?
**此信息适用于使用事件日志 API 的特定系统。坚持使用 C#/PowerShell,您可以运行代码来获取 ProviderMetadata。我打算输入一些代码,但实际上这个特定问题有一个很好的答案,在这个 stackoverflow 帖子中有很多 PowerShell 代码示例:https ://stackoverflow.com/questions/21012622/get-windows-event-provider-信息**
Powershell 代码与我可以为任务计划程序中的触发器配置的内容之间是否存在联系?可能触发器不能做得那么具体,以至于无法监视单个文件的 LastWrite 更改,并且该任务会在各种文件系统事件上被过于频繁地调用。我手头的任务可能是最好的解决方案是在启动时运行 powershell 代码,但是,我真的在寻求对事件如何工作的更深入的了解。
不,Powershell 代码和任务计划程序触发器之间没有任何联系。您经常会看到人们在 Powershell 中使用的另一种类型的事件触发器是 WMI。你也不想使用它。它会有效地不断轮询以运行,这使得它非常低效。始终运行代码是实现此目的的最佳方法,您要么必须使用具有文件系统类型要求并编写更多自己的解析代码的更改日志,要么将轮询和恢复功能添加到使用 FileSystemWatcher 的实现中博客文章中描述。然而,话虽如此,当人们尝试使用 FileSystemWatcher 来完成某些事情时,如果您还控制更改文件的软件,通常会有一个潜在的更好的集成点。
此致,
克里斯
顺便说一句 - 克里斯正在度假,没有时间在这里输入答案,但允许我这样做。当然,他值得称赞。