创建或编辑文件时,如何监视文件夹并触发命令行操作?


82

我需要在Vista机器上设置某种脚本,以便将文件添加到特定文件夹时,它会自动触发对该文件进行操作的后台进程。(后台进程只是一个命令行实用程序,它将文件名和一些其他预定义选项作为参数。)

出于性能和维护的原因,如果可能,我想使用Windows的本机功能。我已经研究过使用Task Scheduler,但是在仔细研究了触发系统一段时间之后,我仍然无法充分理解它,而且我甚至不确定它是否能够满足我的需求。

我将不胜感激任何建议。谢谢!


听起来,您需要像Linux的inotify这样的东西,但是对于Windows。Jnotify可能会有所帮助,但是由于Java太重了。
基思2010年

1
我也想知道...发现了[MSDN页面](msdn.microsoft.com/en-us/library/aa365261 ( VS.85).aspx)
基思2010年

Answers:


92

在工作中,我们使用Powershell监视文件夹。
自Windows Vista(已预安装.NET和PowerShell)以来,就可以使用它,而无需任何其他工具。

该脚本监视特定的文件夹并写入日志文件。您可以替换操作并执行所需的任何操作,例如调用外部工具

日志文件示例

2014年11月23日19:22:04,创建,D:\ source \ New Text Document.txt
2014年11月23日19:22:09,已更改,D:\ source \ New Text Document.txt
2014年11月23日19:22:09,已更改,D:\ source \ New Text Document.txt
2014年11月23日19:22:14,已删除,D:\ source \ New Text Document.txt

StartMonitoring.ps1

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = "D:\source"
    $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
              }    
### 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}

如何使用

  1. 创建一个新的文本文件
  2. 复制并粘贴上面的代码
  3. 根据您的需要更改以下设置:
    • 要监视的文件夹: $watcher.Path = "D:\source"
    • 文件过滤器,仅包含某些文件类型: $watcher.Filter = "*.*"
    • 包括子目录是/否: $watcher.IncludeSubdirectories = $true
  4. 保存并将其重命名为 StartMonitoring.ps1
  5. 通过右键单击开始监视»使用PowerShell执行

要停止监视,仅需关闭PowerShell窗口即可

进一步阅读


效果很好,但是停止脚本的功能是什么?我遇到错误:“ Unregister-Event:因为参数为null,所以无法将其绑定到参数'SourceIdentifier'。” pastebin.com/ugLB3a69
Jan Stanstrup

@JanStanstrup我可能将更多人与第二个脚本混淆了。我将其删除。只需关闭StartWatching.ps1窗口即可停止监视。如果包括它在你的第一个脚本,第二脚本不只是工作,以节省变量$created$changed$deleted$renamed
nixda

感谢您的回答。谁能建议我们是否可以使用cmd提示符,因为我想在更改
后将

5

您似乎处在正确的位置上-您可以使用任务计划程序定期运行.bat或.cmd文件,并且该文件可以以一行开头以检查所需文件的存在-实际上,我d检查文件是否不存在;例如:

@ECHO OFF
REM Example file
IF NOT EXIST C:\SOMEWHERE\SUBFOLDER\THISFILE.THS EXIT 1
REM All this gets done if the file exists...
:
:
EXIT 0

您还可以修改此代码,并使其在循环中运行,例如在循环中延迟1分钟,然后将对批处理文件的引用放在Windows启动文件夹中:

@ECHO OFF
REM Example file
:LOOP    
IF NOT EXIST C:\SOMEWHERE\SUBFOLDER\THISFILE.THS GOTO SKIP01
REM All this gets done if the file exists...
:
:
:SKIP01
REM Crafty 1 minute delay...
PING 1.1.1.1 -n 10 -w 6000 >NUL
GOTO LOOP

根据Windows的运行版本以及安装了哪些其他资源包,还有其他方法可以实现延迟,但是PING命令在任何情况下都可以正常工作。在上面的PING命令中,执行10个幻像PINGS,它们之间的延迟为6000ms(即6秒),您可以使用这些值来实现批处理文件循环之间所需的延迟。


好主意..顺便说一句,C:\> ping 1.1.1.1 -n 10 -w 6000由于某种原因在我的计算机上花了1分钟10秒。但是-n 1 -w 60000正好花了1分钟。
barlop 2010年

@barlop -在10秒差异是由于-n 10VS -n 1

@Randolph Potter 6秒60秒不是10很多吗?和-n 10表示应该使用10次。
barlop 2010年

你也许是对的。我拿回去,怪我的金发。

我最终将此循环用于监视批处理IF NOT EXIST C:\NO_SUCH_FILE_EVER.foo。骇人听闻,但有效。谢谢你的主意。
Snekse 2012年

3

谢谢大家的建议。

我最终编写了一个大致基于Linker3000轮询文件夹的思想并使用Task Scheduler在启动时运行它的VBScript。我最终从该资源中获取了基本语法,并进行了必要的调整。

我仍然想在某个时刻对其进行优化,使脚本的全部内容在事件驱动的系统上运行,但是我已经没有时间来处理它了,而且,这足够好了。

这是脚本,以防万一有人感兴趣(为清晰起见,删除了不相关的转化细分):

' FOLDER TO MONITOR
strFolder = "J:\monitored-folder"

' FREQUENCY TO CHECK IT, IN SECONDS
nFrequency = 10

strComputer = "."
strQueryFolder = Replace(strFolder, "\", "\\\\")
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" &     strComputer & "\root\cimv2") 
Set colMonitoredEvents = objWMIService.ExecNotificationQuery ("SELECT * FROM __InstanceCreationEvent WITHIN " & nFrequency & " WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent='Win32_Directory.Name=""" & strQueryFolder & """'") 

Do 
    Set objLatestEvent = colMonitoredEvents.NextEvent
    strNewFile = objLatestEvent.TargetInstance.PartComponent
    arrNewFile = Split(strNewFile, "=")
    strFilePath = arrNewFile(1)
    strFilePath = Replace(strFilePath, "\\", "\")
    strFilePath = Replace(strFilePath, Chr(34), "")
    strFileName = Replace(strFilePath, strFolder, "")
    strTempFilePath = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) & "\TEMP.M4A"

    ' DO THE OPERATION STUFF
    ' ...
Loop

(此外,我不想让这个问题没有得到正式答复-我不想接受我对问题的回答-但我确实感谢Linker3000的回答!)


2

您可能会看到DropIt(免费)。该程序适用于以某些自动化方式处理传入文件。您可以将参数移动,复制,删除和传递给其他命令行程序,以转换图像,分割PDF等。


2

如果操作只是复制更改的文件,则可以使用robocopy / MON

不知道robocopy是使用FileSystemWatcher还是通过轮询更改来工作


1

或者,您可以使用Watch 4 Folder。显然,它是免费的,可移植的并且与Windows 7兼容。我没有尝试过,但是通过网络搜索找到了它,并认为我会继续使用它。

我也喜欢VBS脚本,该脚本也出现在该网站上。


不幸的是,只有付费版本才是便携式的
nixda

正在考虑使用此软件。您相信它可以监视来自许多用户的重要文件的网络共享吗?
保罗·马修斯

免费版本的Watch4Folder只有一个“示例”条目可以配置。
PeterCo


0

我们使用http://www.myassays.com/folder-poll上的商业工具(即非免费)“文件夹调查” 来执行此操作。这是一个Windows应用程序,包括一个用户友好的管理器应用程序,可轻松进行配置。另外,还有一个XML配置选项。实际的文件夹轮询作为Windows服务运行(因此,每次重新启动时都会自动启动)。当在轮询文件夹中检测到新文件时,可以自动启动应用程序(您可以指定自己的自定义命令行参数)。它也可以做其他事情,例如复制/移动文件。此外,活动可以记录到日志文件中,并且还有其他高级操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.