我需要在我的 Vista 机器上设置某种脚本,以便每当将文件添加到特定文件夹时,它都会自动触发对该文件进行操作的后台进程。(后台进程只是一个命令行实用程序,它将文件名作为参数,以及一些其他预定义选项。)
如果可能的话,出于性能和维护方面的考虑,我想使用 Windows 的原生功能来实现这一点。我考虑过使用任务计划程序,但在仔细研究了触发系统一段时间后,我还是无法理解它的含义,我甚至不确定它是否能够满足我的需要。
我很感激任何建议。谢谢!
答案1
在工作中我们使用 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
开始监控.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}
如何使用
- 创建新的文本文件
- 复制并粘贴以上代码
- 根据您自己的需要更改以下设置:
- 要监视的文件夹:
$watcher.Path = "D:\source"
- 文件过滤器仅包含某些文件类型:
$watcher.Filter = "*.*"
- 包含子目录是/否:
$watcher.IncludeSubdirectories = $true
- 要监视的文件夹:
- 保存并重命名为
StartMonitoring.ps1
- 开始监控右键单击»使用 PowerShell 执行
要停止监控,只需关闭 PowerShell 窗口即可
进一步阅读
答案2
谢谢大家的建议。
我最终编写了一个 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 的回答投了赞成票以表感谢!)
答案3
您似乎走在正确的道路上 - 您可以使用任务计划程序定期运行 .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
您还可以修改此代码并使其循环运行,例如,循环延迟 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 个幻影 PING,每个 PING 之间的延迟为 6000 毫秒(即 6 秒),您可以使用这些值来实现批处理文件循环之间所需的延迟。