注意:运行PowerShell v3
我目前有一个目录设置:
\ftproot\001\converted
\ftproot\001\inbound
\ftproot\001\pdf
\ftproot\002\converted
\ftproot\002\inbound
\ftproot\002\pdf
\ftproot\xxx\converted
\ftproot\xxx\inbound
\ftproot\xxx\pdf
每个FTP用户都映射到入站目录。如果这使得解决方案更容易,则可以更改结构
\ftproot\converted\001
\ftproot\converted\002
\ftproot\converted\xxx
\ftproot\inbound\001
\ftproot\inbound\002
\ftproot\inbound\xxx
\ftproot\pdf\001
\ftproot\pdf\002
\ftproot\pdf\xxx
我需要监视TIFF文件的每个入站目录,并在添加时添加新的FTP用户和入站目录(遵循相同的结构),因此我不打算为每个新用户修改脚本。
目前的脚本如下:
$fileDirectory = "\ftproot";
$folderMatchString = "^[0-9]{3}$";
$inboundDirectory = "inbound";
$filter = "*.tif";
$directories = dir -Directory $fileDirectory | Where-Object {$_.Name -match $folderMatchString}
foreach ($directory in $directories) {
$sourcePath = "$fileDirectory\$directory\$inboundDirectory"
if(Test-Path -Path $sourcePath -pathType container ) {
// Problem is here //
$fsw = New-Object IO.FileSystemWatcher $sourcePath, $filter -Property @{
IncludeSubdirectories = $false
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
}
}
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp"
}
我将New-Object IO.FileSystemWatcher包装在一个循环中,因此在上面的示例中,只会监视最后一个目录。
是否可以创建IO.FileSystemWatcher的数组或列表或类似内容?如果是这样,我如何为每个实例编写Register-ObjectEvent代码?最后将有超过一百个目录要监控(并且增长缓慢),但同样的操作适用于所有入站文件夹。
或者我应该调查一个更好的解决方案吗?
每个FTP用户的过程都是相同的,文件需要在可以链接回用户的目录中说明。将检测入站目录中是否有上传的TIFF文件,当检测到文件时,多页TIFF被拆分为单个文件并移动到转换后的目录中,当在转换中检测到新文件时,对TIFF文件执行另一个操作,然后它被转换为PDF并移动到PDF文件夹。
谢谢
解决方案
$result = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {
$dir = $_;
$fsw = New-Object IO.FileSystemWatcher $dir, $filter -Property @{
IncludeSubdirectories = $false
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
};
$oc = Register-ObjectEvent $fsw Created -Action {
$path = $Event.SourceEventArgs.FullPath;
$name = $Event.SourceEventArgs.Name;
$changeType = $Event.SourceEventArgs.ChangeType;
$timeStamp = $Event.TimeGenerated;
Write-Host "The file '$name' was $changeType at $timeStamp";
};
new-object PSObject -Property @{ Watcher = $fsw; OnCreated = $oc };
});
答案 0 :(得分:1)
是否可以创建数组或列表或类似的IO.FileSystemWatcher?
是。使用管道就像是:
$fsws = $directoriesOfInterest | ? { Test-Path -Path $_ } | % {
new-object IO.FileSystemWatcher …
}
和$fsws
将是一个数组,如果创建了多个观察者(如果只有一个,那将是一个浪费,如果没有,则为$null
)。要始终获取数组,请将管道放入@(…)
:
$fsws = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {
new-object IO.FileSystemWatcher …
})
如果是这样,我如何为每个实例编写Register-ObjectEvent?
将对象注册放在同一个循环中,并返回观察者和事件注册:
$result = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {
# $_ may have a different value in code in inner pipelines, so give it a
# different name.
$dir = $_;
$fsw = new-object IO.FileSystemWatcher $dir, …;
$oc = Register-ObjectEvent $fsw Created …;
new-object PSObject -props @{ Watcher = $fsw; OnCreated = $oc };
})
和$result
将是这两个属性的对象数组。
请注意,传递给-Action
的{{1}}代码可以引用Register-ObjectEvent
和$fsw
,从而知道哪个观察者已经解雇了该事件。