如何监控一个文件夹,并在创建或编辑文件时触发命令行操作?
我需要在我的Vista机器上设置一个脚本,这样每当一个文件被添加到一个特定的文件夹中时,它就会自动触发一个后台进程,并对该文件进行操作。(背景进程只是一个命令行工具,它以文件名作为参数,以及其他一些预定义的选项。)
如果可能的话,我想用Windows的原生功能来做这个工作,出于性能和维护的考虑。我已经研究过使用任务调度器,但在浏览了一段时间的触发器系统后,我还没能对它有什么意义,而且我甚至不确定它是否能满足我的需求。谢谢!
我需要在我的Vista机器上设置一个脚本,这样每当一个文件被添加到一个特定的文件夹中时,它就会自动触发一个后台进程,并对该文件进行操作。(背景进程只是一个命令行工具,它以文件名作为参数,以及其他一些预定义的选项。)
如果可能的话,我想用Windows的原生功能来做这个工作,出于性能和维护的考虑。我已经研究过使用任务调度器,但在浏览了一段时间的触发器系统后,我还没能对它有什么意义,而且我甚至不确定它是否能满足我的需求。谢谢!
在工作中,我们使用Powershell来监控文件夹。
这个脚本可以从Windows Vista开始使用(预装了.NET和PowerShell),不需要任何额外的工具。你可以替换操作,并做任何你想做的事情,例如调用外部工具
11/23/2014 19:22:04, Created, D:\source\New Text Document.txt 11/23/2014 19:22:09, Changed, D:\source\New Text Document.txt 11/23/2014 19:22:09, Changed, D:\source\New Text Document.txt 11/23/2014 19:22:14, Deleted, D:\source\New Text Document.txt
### 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}
$watcher.Path = "D:\source"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
StartMonitoring.ps1
5.开始监控_右键点击 “用PowerShell执行”要停止监控,只需关闭PowerShell窗口
你的思路似乎是对的–你可以使用任务调度器定期运行一个.bat或.cmd文件,这个文件可以以一行开始检查所需的文件是否存在–事实上,我会检查该文件是否不存在;例如:
@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
``` ```
@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
``` &001 &001。 cmd文件,然后这个文件可以在开始时加上一行来检查所需文件是否存在--事实上,我会检查该文件是否不存在;例如:
&001
你也可以修改这段代码,让它在循环中运行,并在循环中延迟1分钟,然后在Windows启动文件夹中添加一个批处理文件的引用。
&001
还有其他的方法可以根据运行的Windows版本和安装了什么额外的资源包来实现延迟,但是PING命令在任何情况下都可以使用。在上面的PING命令中,执行10个幻影PING,它们之间的延迟为6000ms(即:6秒),你可以用这些值来实现批处理文件循环之间的延迟。
我写了一个VBScript,大致上是基于Linker3000的想法,即轮询文件夹,并使用任务调度器让它在启动时运行。我最终从这个资源中得到了基本的语法,并做了必要的调整。
我还想在某个时候优化一下,让脚本的内核在事件驱动的系统上运行,但我已经没有时间去做了,而且,这已经足够好了。
以下是这个脚本,如果有人感兴趣的话(为了清晰起见,把不相关的转换段重新编辑了一下):
' 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 的答案投了高票,作为感谢!)
或者你可以使用Watch 4 Folder。显然,它是免费软件,可移植,并与Windows 7兼容。我还没试过,但通过网络搜索找到了它,我想我会把它传给大家。
我们使用的商业工具(即不是免费的)Folder Poll从http://www.myassays.com/folder-poll 来完成这个任务。它是一个Windows应用程序,包括一个用户友好的管理程序,可以方便地进行配置。另外,它还有一个XML配置选项。实际的文件夹轮询作为一个Windows服务运行(所以每次重启时都会自动启动)。当在轮询文件夹中检测到一个新文件时,一个应用程序可以自动启动(你可以指定你自己的自定义命令行参数)。它还可以做其他事情,比如复制/移动文件。此外,它还可以将活动记录到日志文件中,并有其他高级操作。