如何使用 Compress-Archive 压缩/归档隐藏文件?

Posted

技术标签:

【中文标题】如何使用 Compress-Archive 压缩/归档隐藏文件?【英文标题】:How to zip / archive hidden files using Compress-Archive? 【发布时间】:2019-05-02 05:57:20 【问题描述】:

当使用Compress-Archive 压缩文件夹时,它会跳过所有隐藏文件。

文档页面告诉我们,此 cmdlet 在后台使用 Microsoft .NET Framework API System.IO.Compression.ZipArchive。

有没有办法强制它归档隐藏文件?我在任何地方都找不到这个问题的记录。我试过-Force,但没有帮助。

我目前的解决方法是在压缩之前使用Set-FileAttribute 删除隐藏属性。

【问题讨论】:

我认为Get-ChildItem -Path '...' -Force | Compress-Archive -DestinationPath '...' 会是解决方案,但这会引发Get-Item : Could not find item ... 一个隐藏文件的路径错误。 认为将 force 参数添加到 Compress-Archive 也可以解决此问题,使用 Compress-Archive $test.fullname -Force -DestinationPath test.zip 时出现相同的错误 【参考方案1】:

这看起来像是Compress-Archive cmdlet 中的错误/疏忽。由于 cmdlet 不提供“包含隐藏文件”参数,但通过 -Path-LiteralPath 参数接受源文件的集合,我希望这...

Compress-Archive -Path (
    Get-ChildItem -Path '...' -Force `
        | Select-Object -ExpandProperty 'FullName' `
) -DestinationPath '...'

...或者这个...

Get-ChildItem -Path '...' -Force | Compress-Archive -DestinationPath '...'

...作为将隐藏文件传递给 cmdlet 的一种方式;为Get-ChildItem 指定-Force 参数的键。然而,这两个调用都会引发这些错误......

Get-Item : Could not find item ....
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:814 char:63
+ ... Entry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWr ...
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (...:String) [Get-Item], IOException
    + FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Exception setting "LastWriteTime": "Cannot convert null to type "System.DateTimeOffset"."
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:814 char:25
+ ...             $currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPa ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

...输入列表中的第一个隐藏文件。 (请注意,在没有Select-Object -ExpandProperty 'FullName' 的情况下调用第一个sn-p 会抛出Compress-Archive : The path '...' either does not exist or is not a valid file system path.。)

在我的系统上,the referenced lines 812-814 和 Microsoft.PowerShell.Archive.psm1 是...

# Updating  the File Creation time so that the same timestamp would be retained after expanding the compressed file. 
# At this point we are sure that Get-ChildItem would succeed.
$currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime

因此,即使我们将-Force 传递给Get-ChildItem 以获取隐藏文件对象的路径以传递给Compress-Archive,cmdlet 在内部仍会使用Get-Item 再次获取这些文件对象...但它不是通过-Force,当然会失败(尽管前一行的评论声称)。因此,我认为没有任何方法可以让 Compress-Archive 处理隐藏文件,而无需您或 Microsoft 编辑该脚本。

【讨论】:

看起来需要为此提出一个问题:github.com/powershell/powershell/issues @JamesC。我提出了这个问题 我也在Microsoft.PowerShell.Archive GitHub repository 中为此打开了an issue。【参考方案2】:

我刚遇到同样的问题,这就是我解决它的方法

# WARNING: This only works on a windows based powershell core terminal instance.
# In a linux based powershell core instance the .dot files are not included in 
# the final archive when using the -Filter example

# This will include .files like .gitignore
Get-ChildItem -Path . -Filter *.* | Compress-Archive -DestinationPath dist.zip

# This will include .dot files like .gitignore and any that are hidden like .git
Get-ChildItem -Path . -Force | Compress-Archive -DestinationPath dist.zip

【讨论】:

【参考方案3】:

我将Compress-Archive 替换为\[System.IO.Compression.ZipFile]::CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName) 并发现(至少在macOS 上)ZIP 文件包含一个以. 开头的目录(这是在macOS 上隐藏目录/文件的一种方法)。这是使用 PowerShell 7.2。

【讨论】:

我已经在 Windows 上使用 system.io.compression.zipfileextensions.createentryfromfile 进行了测试,它压缩了隐藏文件,只要您使用 -Force 参数到 Get-ChildItem 就可以找到文件。在我的测试中,隐藏属性未保留在存档中。有关在存档中存储路径的示例,请参阅 this answer。【参考方案4】:

嗯……那真的很烦人! 我已经开始通过 Powershell 使用 7-Zip,但这当然意味着我正在使用另一种工具。这也意味着使用 Compress-Archive 几乎是多余的。

这是我的脚本的一部分,其中包含 7Zip 变量和压缩内容:

    $7ZipPath = "$env:ProgramFiles\7-Zip\7z.exe"
    
    If (-Not (Test-Path -Path $7ZipPath -PathType Leaf)) 
        throw "7 Zip File '$7ZipPath' Not Found"
    PAUSE
    
    
    Set-Alias 7Zip $7ZipPath 
    
    $ItemsToZip = @
    Path= "$TempDirectory\*"
    CompressionLevel = "Fastest"
    DestinationPath = $MyZipFile
    
    Compress-Archive @ItemsToZip
    
    7zip u $MyZipFile -ux2y2z2 "C:\Path\HiddenFile.ext"

希望对某人有所帮助

【讨论】:

以上是关于如何使用 Compress-Archive 压缩/归档隐藏文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Read-Host 运行 Compress-Archive

压缩存档,排除包含文件夹

Windows 7中未知的Compress-Archive powershell命令

使用 7zip 压缩 powershell 5.0

Powershell Compress-Archive 对老化文件

Powershell Compress-Archive 文件到文件夹中