繁体   English   中英

Filesystemwatcher 文件创建事件未解压缩文件

[英]Filesystemwatcher file created event not decompressing files

我有一个简单的脚本,它应该监视指定文件夹中的新文件并在到达时解压缩它们。 很简单,但我的脚本只能在 Powershell ISE 的调试器下工作。 在调试器之外,在创建文件时,它只打印“找到新文件 xxx”和“完成”,没有解压缩,也没有删除,也没有错误。 我在这里错过了什么吗?

# Folder you to monitor
$PathToMonitor = "C:\tmp1".
$OutputPath = "C:\tmp"
$Filter = "*.zip"  # Filter for zip files.

$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path  = $PathToMonitor
$FileSystemWatcher.IncludeSubdirectories = $false
$FileSystemWatcher.Filter = $Filter

# make sure the watcher emits events
$FileSystemWatcher.EnableRaisingEvents = $true

# define the code that should execute when a file change is detected
$Action = {
    $details = $event.SourceEventArgs
    $FullPath = $details.FullPath
    $OldName = $details.OldName
    $Timestamp = $event.TimeGenerated
    try
    {
        Write-Host "New file " + $FullPath + " found"
        $TarProgram = "tar.exe"
        $TarArgs = 'xvf "' + $FullPath + '" -C ' + $OutputPath
        Start-Process $TarProgram $TarArgs -Wait -WindowStyle hidden
        Remove-Item -Path $FullPath -Force
        Write-Host "Done"
    }
    catch [System.SystemException]
    {
        Write-Host $_.ScriptStackTrace
    }
}

# add event handlers
$handlers = . {
    Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreateFtpGe
}

Write-Host "Watching for changes to $PathToMonitor"

try
{
    do
    {
        Wait-Event -Timeout 10
    } while ($true)
}
catch [System.SystemException]
{
    Write-Host $_.ScriptStackTrace
}
finally
{
    # this gets executed when user presses CTRL+C
    # remove the event handlers
    Write-Host "Cleaning up"
    Unregister-Event -SourceIdentifier FSCreateFtpGe
    # remove background jobs
    $handlers | Remove-Job
    # remove filesystemwatcher
    $FileSystemWatcher.EnableRaisingEvents = $false
    $FileSystemWatcher.Dispose()
    "Event Handler disabled."
}

你怎么来月经了...

$PathToMonitor = "C:\tmp1".

...这是无效的语法,脚本无论如何都会失败。 然而,这可能只是您在此处发布的一种类型。

您为什么使用 tar 与 PowerShell 内置存档 cmdlet?

如果 tar.exe 不在您的 PowerShell 或系统路径中,您必须完全限定该路径才能使用它。

$TarProgram = 'C:\ProgramFiles\tar.exe'

因此,您的代码应该可以在任何 PowerShell 主机(ISE [进入/退出调试模式])/powershell.exe/VSCode 等中运行。 正如我刚刚测试过的那样。 再一次,cmdlet 在那里。 以下示例在新的 Windows 终端中运行。

#region Begin Script

# Folder you to monitor
$PathToMonitor = 'D:\tmp1'
$OutputPath    = 'D:\tmp'
$Filter        = '*.zip'  # Filter for zip files.

$FileSystemWatcher        = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path   = $PathToMonitor
$FileSystemWatcher.IncludeSubdirectories = $false
$FileSystemWatcher.Filter = $Filter

# make sure the watcher emits events
$FileSystemWatcher.EnableRaisingEvents = $true

# define the code that should execute when a file change is detected
$Action = {
    $details   = $event.SourceEventArgs
    $FullPath  = $details.FullPath
    $OldName   = $details.OldName
    $Timestamp = $event.TimeGenerated

    try
    {
        "New file $FullPath  found"
        Expand-Archive -Path $FullPath -DestinationPath 'D:\tmp'

        # Start-Process $TarProgram $TarArgs -Wait -WindowStyle hidden
        Remove-Item -Path $FullPath -Force

        'Done'
    }
    catch [System.SystemException]
    {$PSItem.ScriptStackTrace}
}

# add event handlers
$handlers = . {
    $RegisterObjectEventSplat = @{
        InputObject      = $FileSystemWatcher
        EventName        = 'Created'
        Action           = $Action
        SourceIdentifier = 'FSCreateFtpGe'
    }
    Register-ObjectEvent @RegisterObjectEventSplat
}

"Watching for changes to $PathToMonitor"

try
{
    do { Wait-Event -Timeout 10 } 
    while ($true)
}
catch [System.SystemException]
{$_.ScriptStackTrace}
finally
{
    <#
    this gets executed when user presses CTRL+C
    remove the event handlers
    #>
    'Cleaning up'
    Unregister-Event -SourceIdentifier FSCreateFtpGe

    # remove background jobs
    $handlers | 
    Remove-Job

    # remove filesystemwatcher
    $FileSystemWatcher.EnableRaisingEvents = $false
    $FileSystemWatcher.Dispose()
    'Event Handler disabled.'
}

#endregion End Script


# Results

 Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property Caption, Version

Caption                  Version
$PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18362.752
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.752}
BuildVersion                   10.0.18362.752
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3

 Get-ChildItem -Path 'D:\tmp' -Verbose
 (Get-ChildItem -Path 'D:\tmp').Count
0
 Get-ChildItem -Path 'D:\tmp1' -Verbose
 (Get-ChildItem -Path 'D:\tmp1').Count
0
 .\FSWCopyUnzip.ps1
Watching for changes to D:\tmp1
New file D:\tmp1\book1.zip  found
Done
Cleaning up

 Get-ChildItem -Path 'D:\tmp' -Verbose


    Directory: D:\tmp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        13-Mar-20     12:19             70 abc.txt
-a----        13-Mar-20     22:27             71 book1.txt
-a----        06-Apr-20     21:51           2979 Data.zip
-a----        04-Mar-20     01:04             72 FileWithLines.txt


 Get-ChildItem -Path 'D:\tmp1' -Verbose
 (Get-ChildItem -Path 'D:\tmp1').Count
 0

只是为了记录,我发现了问题。 它在某种程度上与 Powershell 中的变量范围有关。 如果不是使用在脚本开头声明的变量来保存 $OutputPath 的值,而是使用文字字符串,那么它可以工作。 否则,它会在运行时抱怨该值为 null (在 Powershell ISE 中它显示一个值)

所以,动作块现在看起来像这样:

$Action = {
    $details = $event.SourceEventArgs
    $FullPath = $details.FullPath
    $OldName = $details.OldName
    $Timestamp = $event.TimeGenerated
    try
    {
        Expand-Archive -LiteralPath $FullPath -DestinationPath "C:\Temp"
        Remove-Item -LiteralPath "$FullPath" -Force
    }
    catch [System.SystemException]
    {
        Write-Host $_
    }
}

我希望一开始就拥有我的所有变量,因此如果需要可以轻松更改它们,但至少这个版本有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM