【问题标题】:How to expand ZIP archive using PowerShell (UTF-8 filenames)如何使用 PowerShell(UTF-8 文件名)扩展 ZIP 存档
【发布时间】:2020-02-14 21:37:28
【问题描述】:

我的 zip 存档只有一个文件:

Père-Noël.txt

使用 Windows 文件资源管理器、7-Zip 或我尝试过的任何其他工具可以很好地扩展 zip。但我无法弄清楚如何从 PowerShell 中做到这一点。显然我已经尝试过Expand-Archive,但它无法处理文件名并将其乱码成PŠre-N”el.txt。注意:问题不在于此示例,而确实存在于任何使用 ASCII-127 范围之外的字符的文件名。或者看起来是这样。

任何使用 PowerShell 且不依赖外部工具的解决方案(无法保证其存在)都将被接受。 Windows 10 是平台。我无法进行系统级别的更改,也不能依赖脚本的用户在其系统上具有任何特定的全局设置。它必须是脚本的解决方案。

除了Expand-Archive,还有其他方法吗?或者 PowerShell 中是否有一个设置可以神奇地做到这一点?

重现步骤:

在您的 Windows 10 主机上:

  1. 创建一个名为 Père-Noël.txt 的空文件。

  2. 使用 Windows 资源管理器(“压缩文件夹”功能)将文件压缩到您选择的 ZIP 存档中,例如 myarchive.zip

  3. 删除Père-Noël.txt文件。

  4. 现在尝试使用 PowerShell 解压缩 myarchive.zip。此操作应再次创建文件Père-Noël.txt

使用 PowerShell Compress-Archive cmdlet 进行压缩

没错,如果 ZIP 最初是使用 Compress-Archive cmdlet 创建的,那么在使用 Expand-Archive 解压缩时它实际上可以正常工作。所以你可以说 PowerShell 是与自身兼容的。它只是与 Windows Explorer ZIP 不兼容。

【问题讨论】:

  • @Matthew:那家伙在 OSx 和 Linux 上。我在 Windows 上。这个问题专门针对 PowerShell。
  • 用powershell创建存档会更好。
  • 文件名解码隐藏在System.IO.Compression.ZipArchiveEntry.DecodeEntryName(byte[] entryNameBytes)中。它默认使用Encoding.GetEncoding(0)。我看不到任何使用反射来覆盖它的方法。您可以尝试选择与 zip 文件中的编码匹配的默认系统编码。就我而言,我使用了西里尔文文件名,正确的编码是 CP866,但系统编码不同。

标签: windows powershell


【解决方案1】:

您可能需要检查编码[System.Text.Encoding]::GetEncodings(),但以下代码适用于您的示例Père-Noël

$zipfile = 'C:\test\Père-Noël.zip' #Contains Père-Noël.txt
$outpath = 'C:\test\out'
$enc = [System.Text.Encoding]::GetEncoding(29001) #29001, x-Europa, Europa
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath, $enc)

希望对你有帮助,

【讨论】:

  • 我认为你误解了这个例子。使用 ASCII-127 范围之外的字符的是 ZIP within 的条目,而不是 ZIP 存档本身的名称。
  • @peterh 没有误解,zip 包含 Père-Noël.txt。 7-zip 用于创建测试文件,默认采用压缩项目的名称。
  • 好的,知道了。这让我很困惑。我会测试一下。
  • 宾果游戏!这对我有用。我已经使用 Windows 资源管理器(“压缩文件夹”)、7-Zip 文件管理器和 Powershell 中的 Compress-Archive cmdlet 创建的存档进行了测试。所有这些都使用此解决方案正确扩展。谢谢。
【解决方案2】:

虽然我们在 2021 年到达,但我偶然发现了同样的问题。 就像接受的答案一样,我的解决方案基于 System.IO.Compression 命名空间。 expand-archive 命令接受管道输入和 -Force 开关。 我的实施目标相同 - 仍在工作中,尚未经过全面测试。

$encoding = [System.Text.Encoding]::GetEncoding(437)
Write-Output $encoding
Get-ChildItem -Path ".\*.zip"  | Unzip -target "C:\unzipped" -f -encoding $encoding -v

Find unzip function here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2017-03-17
    • 2015-05-27
    相关资源
    最近更新 更多