FileWatchers имеют причуды, в зависимости от того, как создаются файлы :
В некоторых ситуациях вы можете заметить, что одно событие создания
генерирует несколько созданных событий, которые обрабатываются вашим компонентом.
Например, если вы используете компонент FileSystemWatcher для мониторинга
создание новых файлов в каталоге, а затем проверить его с помощью
Блокнот для создания файла, вы можете увидеть два созданных события, созданные
хотя был создан только один файл. Это потому что блокнот
выполняет несколько действий файловой системы в процессе записи.
Блокнот записывает на диск пакетами, которые создают содержимое
файл, а затем атрибуты файла. Другие приложения могут выполнять в
таким же образом. Потому что FileSystemWatcher контролирует работающие
системные действия, все события, которые будут запускать эти приложения
взял.
Примечание. Блокнот также может вызывать другие интересные события. За
Например, если вы используете ChangeEventFilter, чтобы указать, что вы хотите
следите только за изменениями атрибутов, а затем вы записываете в файл в
каталог, который вы смотрите с помощью блокнота, вы будете вызывать событие.
Это связано с тем, что Блокнот обновляет атрибут Archived для файла
во время этой операции.
Так что в вашем случае я бы пошел с простым сравнением каталогов. Вот скрипт, который будет отслеживать каталог на наличие изменений и запускать файлы. Сохранить этот скрипт как MonitorAndExecute.ps1
, Он принимает следующие аргументы:
- Дорожка : папка для мониторинга. Если не указан, используется текущий каталог.
- Фильтр : расширение файла для соответствия. По умолчанию
*
то есть сопоставить все файлы.
- Бежать : расширение файла для запуска, когда новый файл найден. По умолчанию
bat
,
- Recurse : исправлять каталоги или нет. По умолчанию установлено значение false.
- интервал : время в секундах для сна между просмотром папки. По умолчанию
5
секунд.
- Подробный : Сценарий расскажет вам, что происходит через
Write-Verbose
Сообщения.
Пример (запускается из консоли PowerShell).
монитор *.pdf
файлы в папке D:\XXXX\XXXX
, recurse, если новый файл найден, запустить файл с тем же базовым именем и расширением *.bat
, будь многословен:
.\MonitorAndExecute.ps1 -Path 'D:\XXXX\XXXX' -Filter '*.pdf' -Run 'bat' -Recurse -Interval 10 -Verbose
MonitorAndExecute.ps1
сценарий:
Param
(
[Parameter(ValueFromPipelineByPropertyName = $true)]
[ValidateScript({
if(!(Test-Path -LiteralPath $_ -PathType Container))
{
throw "Input folder doesn't exist: $_"
}
$true
})]
[ValidateNotNullOrEmpty()]
[string]$Path = (Get-Location -PSProvider FileSystem).Path,
[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]$Filter = '*',
[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]$Run = 'bat',
[Parameter(ValueFromPipelineByPropertyName = $true)]
[switch]$Recurse,
[Parameter(ValueFromPipelineByPropertyName = $true)]
[int]$Interval = 5
)
# Scriptblock that gets list of files
$GetFileSet = {Get-ChildItem -LiteralPath $Path -Filter $Filter -Recurse:$Recurse | Where-Object {!($_.PSIsContainer)}}
Write-Verbose 'Getting initial list of files'
$OldFileSet = @(. $GetFileSet)
do
{
Write-Verbose 'Getting new list of files'
$NewFileSet = @(. $GetFileSet)
Write-Verbose 'Comaparing two lists using file name and creation date'
Compare-Object -ReferenceObject $OldFileSet -DifferenceObject $NewFileSet -Property Name, CreationTime -PassThru |
# Select only new files
Where-Object { $_.SideIndicator -eq '=>' } |
# For each new file...
ForEach-Object {
Write-Verbose "Processing new file: $($_.FullName)"
# Generate name for file to run
$FileToRun = (Join-Path -Path (Split-Path -LiteralPath $_.FullName) -ChildPath ($_.BaseName + ".$Run"))
# If file to run exists
if(Test-Path -LiteralPath $FileToRun -PathType Leaf)
{
Write-Verbose "Running file: $FileToRun"
&$FileToRun
}
else
{
Write-Verbose "File to run not found: $FileToRun"
}
}
Write-Verbose 'Setting current list of files as old for the next loop'
$OldFileSet = $NewFileSet
Write-Verbose "Sleeping for $Interval seconds..."
Start-Sleep -Seconds $Interval
}
while($true)