Как отслеживать папку и запускать действие командной строки при создании или редактировании файла?

82

Мне нужно установить какой-то сценарий на моем компьютере с Vista, чтобы всякий раз, когда файл добавлялся в определенную папку, он автоматически запускал фоновый процесс, который работает с файлом. (Фоновый процесс - это просто утилита командной строки, которая принимает имя файла в качестве аргумента вместе с некоторыми другими предопределенными параметрами.)

Я хотел бы сделать это, используя встроенные функции Windows, если это возможно, из соображений производительности и обслуживания. Я изучал использование планировщика заданий, но после некоторого изучения системы триггеров у меня не получилось осознать это, и я даже не уверен, что она способна делать то, что мне нужно.

Буду признателен за любые предложения. Спасибо!

bigmattyh
источник
Похоже, вам нужно что-то вроде Inotify Linux, но для Windows. Jnotify может помочь, но так как это Java может быть слишком тяжелым.
Кит
1
Мне тоже было интересно об этом ... нашел [страницу MSDN] ( msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx) .
Кит
2
Ссылка выше имеет) после aspx: msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx
вс

Ответы:

92

На работе мы используем Powershell для мониторинга папок.
Его можно использовать начиная с Windows Vista (предварительно установлены .NET и PowerShell) без каких-либо дополнительных инструментов.

Этот скрипт отслеживает определенную папку и записывает файл журнала. Вы можете заменить действие и делать все, что хотите, например, вызвать внешний инструмент

Пример файла журнала

23.11.2014 19:22:04, Создано, D: \ source \ New Text Document.txt
23.11.2014 19:22:09, Изменено, D: \ source \ New Text Document.txt
23.11.2014 19:22:09, Изменено, D: \ source \ New Text Document.txt
23.11.2014 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.

дальнейшее чтение

nixda
источник
Работает хорошо, но какова функция скрипта остановки? Я получаю сообщения об ошибках: «Unregister-Event: невозможно связать аргумент с параметром« SourceIdentifier », потому что он нулевой». pastebin.com/ugLB3a69
Ян Станструп
@JanStanstrup Я, вероятно, перепутал больше людей со вторым сценарием. Я удалю это. Достаточно просто закрыть StartWatching.ps1окно, чтобы остановить мониторинг. Второй скрипт работает только , если вы включите его в свой первый сценарий , чтобы сохранить переменные $created, $changed, $deletedили$renamed
nixda
Спасибо за ответ. Может кто-нибудь предложить, если бы мы могли использовать приглашение cmd, поскольку я хочу загружать файлы в github при изменении
m__
5

Вы, кажется, находитесь на правильных строках - вы можете использовать планировщик задач для регулярного запуска файла .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 фантомных PINGS выполняются с задержкой 6000 мс (то есть: 6 секунд) между ними, вы можете поиграть с этими значениями, чтобы добиться необходимой задержки между циклами пакетного файла.

Linker3000
источник
хорошая идея .. кстати, C: \> ping 1.1.1.1 -n 10 -w 6000 почему-то заняло 1мин 10 секунд на моем компьютере. но -n 1 -w 60000 занял ровно 1 минуту.
Барлоп
@ barlop - несоответствие за десять секунд связано с -n 10против -n 1.
@ Рэндольф Поттер Не 10 лотов по 6 секунд, 60 секунд? и -n 10, который вы используете, должен означать 10 раз.
Barlop
Возможно ты прав. Я забираю это и обвиняю мои светлые волосы.
Я закончил тем, что использовал этот цикл для контрольного пакета IF NOT EXIST C:\NO_SUCH_FILE_EVER.foo. Взломать, но это работает. Спасибо за идею.
Снексе
3

Спасибо всем за предложения.

Я закончил тем, что написал 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 в качестве благодарности!)

bigmattyh
источник
2

Вы можете посмотреть на DropIt (бесплатно). Программа подходит для обработки входящих файлов некоторыми автоматическими способами. Вы можете перемещать, копировать, удалять и передавать параметры в другие программы командной строки для преобразования изображений, разделения PDF-файлов и т. Д.

солнце
источник
2

Если действие просто копировать измененные файлы, вы можете использовать robocopy / MON

Не знаю, использует ли robocopy FileSystemWatcher или работает путем опроса изменений

weberjn
источник
1

Или вы можете использовать Watch 4 Folder . По всей видимости, он бесплатный, переносимый и совместимый с Windows 7. Я не пробовал его, но нашел его с помощью веб-поиска и подумал, что передам его.

Мне также нравится сценарий VBS, также размещенный на сайте.

Крис
источник
К сожалению, только платная версия является портативной
nixda
Думал об использовании этого программного обеспечения. Доверяете ли вы этому, чтобы отслеживать общий сетевой ресурс с важными файлами от многих пользователей?
Пол Мэтьюз
Бесплатная версия Watch4Folder имеет только одну «пробную» запись, которую можно настроить.
PeterCo
0

Мы используем коммерческий инструмент (то есть, не бесплатный) Folder Poll с http://www.myassays.com/folder-poll, чтобы сделать это. Это приложение для Windows, которое включает в себя удобное приложение-менеджер для упрощения настройки. Также есть опция конфигурации XML. Фактический опрос папок выполняется как служба Windows (поэтому запускается автоматически при каждом перезапуске). Когда в опрашиваемой папке обнаруживается новый файл, приложение может запускаться автоматически (вы можете указать свои собственные аргументы командной строки). Это может делать другие вещи, такие как копирование / перемещение файлов тоже. Кроме того, активность может быть записана в файл журнала, и есть другие дополнительные операции.

Мистер Кук
источник