如何使用“压缩存档”压缩/存档隐藏文件?

时间:2018-11-30 04:49:08

标签: powershell zip compression zipfile hidden-files

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

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

是否有某种方法可以强制它存档隐藏文件?我找不到任何地方记录此问题。我尝试-Force实在是无济于事。

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

3 个答案:

答案 0 :(得分:3)

这似乎是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的一种方式;密钥正在为-Force指定Get-ChildItem参数。但是,这两个调用都引发了这些错误...

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'的情况下调用第一个代码段会抛出Compress-Archive : The path '...' either does not exist or is not a valid file system path.。)

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

# 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仍在内部使用{{1 }} ...但是它没有通过Get-Item,这当然会失败(尽管对前一行的评论声称)。因此,我认为没有您或Microsoft编辑该脚本,没有任何方法可以使-Force处理隐藏文件。

答案 1 :(得分:1)

好吧……那真令人讨厌! 我已经习惯通过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"

希望能帮助到某人

答案 2 :(得分:1)

我刚刚遇到了同样的问题,这就是我的想法

# 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