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

Gui*_*ing 6 compression powershell zip zipfile hidden-files

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

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

有没有办法强迫它存档隐藏文件?我无法在任何地方找到此问题.我试过-Force它,没有帮助.

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

Mic*_*out 6

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

  • 我已经使用 [system.io.compression.zipfileextensions.createentryfromfile](https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.zipfileextensions.createentryfromfile?view=net-6.0 进行了测试)在 Windows 上,它会压缩隐藏文件,只要您对“Get-ChildItem”使用“-Force”参数,它就会找到文件。在我的测试中,隐藏属性未保留在存档中。有关在存档中存储路径的示例,请参阅[此答案](/sf/ask/4912027851/#70173927) 。 (2认同)

BAC*_*CON 5

This looks like a bug/oversight in the Compress-Archive cmdlet. Since the cmdlet provides no "include hidden files" parameter but does accept a collection of source files via the -Path or -LiteralPath parameters, I would expect either this...

Compress-Archive -Path (
    Get-ChildItem -Path '...' -Force `
        | Select-Object -ExpandProperty 'FullName' `
) -DestinationPath '...'
Run Code Online (Sandbox Code Playgroud)

...or this...

Get-ChildItem -Path '...' -Force | Compress-Archive -DestinationPath '...'
Run Code Online (Sandbox Code Playgroud)

...to work as a way of passing hidden files to the cmdlet; the key being specifying the -Force parameter for Get-ChildItem. Both of those invocations, however, throw these errors...

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
Run Code Online (Sandbox Code Playgroud)

...for the first hidden file in the input list. (Note that invoking the first snippet without Select-Object -ExpandProperty 'FullName' instead throws Compress-Archive : The path '...' either does not exist or is not a valid file system path..)

On my system, the referenced lines 812-814 of Microsoft.PowerShell.Archive.psm1 are...

# 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
Run Code Online (Sandbox Code Playgroud)

So, even if we pass -Force to Get-ChildItem to get the paths of hidden file objects to pass to Compress-Archive, internally the cmdlet is fetching those file objects again using Get-Item...but it's not passing -Force, which of course will fail (despite what the comment on the previous line claims). Thus, I don't think there's any way to get Compress-Archive to work with hidden files without either you or Microsoft editing that script.

  • 我在 [`Microsoft.PowerShell.Archive` GitHub 存储库](https://github.com) 中为此打开了 [一个问题](https://github.com/PowerShell/Microsoft.PowerShell.Archive/issues/66) /PowerShell/Microsoft.PowerShell.Archive) 也是如此。 (3认同)