2010-12-29 08:06:29 +0000 2010-12-29 08:06:29 +0000
87
87

Como monitorar uma pasta e acionar uma ação de linha de comando quando um arquivo é criado ou editado?

Eu preciso configurar algum tipo de script na minha máquina Vista, para que sempre que um arquivo é adicionado a uma determinada pasta, ele acione automaticamente um processo de fundo que opera no arquivo. (O processo em background é apenas um utilitário de linha de comando que toma o nome do ficheiro como argumento, juntamente com algumas outras opções pré-definidas)

Gostaria de o fazer utilizando funcionalidades nativas do Windows, se possível, por razões de performance e manutenção. Já investiguei a utilização do Task Scheduler, mas depois de ter lido o sistema de trigger durante algum tempo, não consegui fazer muito sentido e nem sequer tenho a certeza se é capaz de fazer o que preciso.

Agradecia quaisquer sugestões. Obrigado!

Respostas (8)

96
96
96
2014-11-23 18:26:49 +0000

No trabalho usamos Powershell para monitorizar pastas. Pode ser usado desde o Windows Vista (.NET e PowerShell está pré-instalado) sem qualquer ferramenta adicional.

Este script monitoriza uma determinada pasta e escreve um ficheiro de registo. Pode substituir a acção e fazer o que quiser, por exemplo, chamar uma ferramenta externa

Exemplo de ficheiro de registo

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

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}

Como usar

  1. Criar um novo ficheiro de texto
  2. Copiar e colar o código acima
  3. Alterar as seguintes definições para as suas próprias necessidades:
  4. pasta para monitorizar: $watcher.Path = "D:\source"
  5. filtro de ficheiros para incluir apenas certos tipos de ficheiros: $watcher.Filter = "*.*"
  6. incluir subdirectórios sim/não: $watcher.IncludeSubdirectories = $true
  7. Guarde e renomeie para StartMonitoring.ps1
  8. Comece a monitorização por clique direito “ Executar com PowerShell

Para parar a monitorização, basta fechar a sua janela PowerShell

Leitura adicional

6
6
6
2010-12-29 08:49:30 +0000

Parece estar na linha certa - poderia usar o programador de tarefas para executar um .bat ou . cmd numa base regular e esse ficheiro poderia começar com uma linha para verificar a existência do ficheiro requerido - de facto, eu verificaria a não existência do ficheiro; por exemplo:

@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

Também poderia modificar este código e fazê-lo correr num laço com um, digamos, atraso de 1 minuto no laço e depois colocar uma referência ao ficheiro batch na pasta de arranque do 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

Existem outras formas de conseguir um atraso de acordo com a versão do Windows em execução e quais kits de recursos adicionais foram instalados, mas o comando PING funciona praticamente em todas as circunstâncias. No comando PING acima, 10 PINGS fantasmas são executados com um atraso de 6000ms (ou seja: 6 segundos) entre eles, você pode jogar com esses valores para conseguir o atraso que você precisa entre loops de arquivos em lote.

4
4
4
2011-01-07 04:01:48 +0000

Obrigado a todos pelas sugestões.

Acabei por escrever um VBScript que se baseou aproximadamente na ideia do Linker3000 de pesquisar a pasta, e usar o Agendador de Tarefas para que fosse executado no arranque. Acabei por obter a sintaxe básica do este recurso e fiz as correcções necessárias.

Ainda gostaria de o optimizar em algum momento, tendo a coragem de executar o script num sistema orientado por eventos, mas fiquei sem tempo para trabalhar nele, e, bem, isto é bom o suficiente.

Aqui está o script, caso alguém esteja interessado (com o segmento de conversão irrelevante redaccionado para clareza):

' 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

(Também não quero deixar esta pergunta oficialmente sem resposta - e detesto aceitar a minha própria resposta à pergunta - mas eu invoquei a resposta do Linker3000 como um agradecimento!)

3
3
3
2016-11-30 09:15:20 +0000

Se a acção é apenas copiar ficheiros alterados, pode utilizar o robocopy /MON

Não sei se o robocopy utiliza o FileSystemWatcher ou funciona através de sondagens para alterações

2
2
2
2011-03-12 13:01:15 +0000

Ou pode usar Ver 4 Pastas . Aparentemente é Freeware, portátil, e compatível com o Windows 7. Ainda não o experimentei, mas encontrei-o através de uma pesquisa na web e pensei em passá-lo adiante.

Também gosto do script VBS, também apresentado no site.

2
2
2
2016-05-16 17:14:11 +0000

Pode consultar DropIt (gratuito). O programa é apropriado para processar arquivos recebidos de algumas formas automatizadas. Você pode mover, copiar, apagar e passar parâmetros para outros programas de linha de comando para converter imagens, dividir PDFs, etc.

2
2
2
2017-12-20 02:16:44 +0000

Também encontrei watchman que parece ser bastante grande, e um watchchexec mais pequeno que ainda não experimentei.

Watchman sente-se bem e programático. Um utilitário CLI para utilizadores de energia.

1
1
1
2016-04-14 08:34:08 +0000

Utilizamos a ferramenta comercial (ou seja, não gratuita) Folder Poll da http://www.myassays.com/folder-poll para fazer exactamente isto. É uma aplicação Windows que inclui uma aplicação de gestão fácil de utilizar para permitir uma configuração fácil. Além disso, existe uma opção de configuração XML. A sondagem da pasta real corre como um serviço do Windows (por isso inicia automaticamente em cada reinício). Quando um novo ficheiro é detectado numa pasta pesquisada, uma aplicação pode ser iniciada automaticamente (pode especificar os seus próprios argumentos de linha de comando personalizados). Também pode fazer outras coisas como copiar/move ficheiros. Além disso, a actividade pode ser registada num ficheiro de registo e existem outras operações avançadas.