我有一个 .zip
文件,需要使用 Powershell 解压缩其全部内容。我正在这样做,但它似乎不起作用:
$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("C:\a.zip")
MkDir("C:\a")
foreach ($item in $zip.items()) {
$shell.Namespace("C:\a").CopyHere($item)
}
怎么了?目录 C:\a
仍为空。
Expand-Archive
现在存在于 powershell 中,因此接受的答案有点过时了。
在 PowerShell v5+ 中,内置了一个 Expand-Archive command(以及 Compress-Archive):
Expand-Archive c:\a.zip -DestinationPath c:\a
以下是使用 System.IO.Compression.ZipFile 中的 ExtractToDirectory 的简单方法:
Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
{
param([string]$zipfile, [string]$outpath)
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}
Unzip "C:\a.zip" "C:\a"
请注意,如果目标文件夹不存在,ExtractToDirectory 将创建它。其他注意事项:
现有文件不会被覆盖,而是会触发 IOException。
此方法至少需要 .NET Framework 4.5,适用于 Windows Vista 和更高版本。
不根据当前工作目录解析相对路径,请参阅为什么 PowerShell 中的 .NET 对象不使用当前目录?
也可以看看:
如何压缩和提取文件 (Microsoft Docs)
shell
脚本语言的好处之一。:-)
Exception calling "ExtractToDirectory" with "2" argument(s): "End of Central Directory record could not be found." At line:5 char:5 + [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $ou ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : InvalidDataException
Add-Type : Cannot add type. The assembly 'System.IO.Compression.FileSystem' could not be found.
。我已经安装了 .NET 4.6.2,并且我已经验证了该程序集在 GAC 中,但我不知道为什么会出现这个错误。
在 PowerShell v5.1 中,这与 v5 略有不同。根据 MS 文档,它必须有一个 -Path
参数来指定存档文件路径。
Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference
否则,这可能是一条实际路径:
Expand-Archive -Path c:\Download\Draft.Zip -DestinationPath C:\Reference
Expand-Archive Draft.Zip -DestinationPath C:\Reference
可以正常工作。另外,它不是实际路径,而是绝对路径。
将 Expand-Archive
cmdlet 与参数集之一一起使用:
Expand-Archive -LiteralPath C:\source\file.Zip -DestinationPath C:\destination
Expand-Archive -Path file.Zip -DestinationPath C:\destination
嘿它为我工作..
$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("put ur zip file path here")
foreach ($item in $zip.items()) {
$shell.Namespace("destination where files need to unzip").CopyHere($item)
}
CopyHere
方法。我猜@OlegKazakov 已经解决了他的问题。尽管如此,我还是将此链接放在这里以供其他可以找到此主题的冲浪者使用:docs.microsoft.com/en-us/previous-versions/windows/desktop/…
使用内置的 powershell 方法 Expand-Archive
例子
Expand-Archive -LiteralPath C:\archive.zip -DestinationPath C:\
使用 expand-archive
但自动创建以存档命名的目录:
function unzip ($file) {
$dirname = (Get-Item $file).Basename
New-Item -Force -ItemType directory -Path $dirname
expand-archive $file -OutputPath $dirname -ShowProgress
}
outputPath
会更加灵活。在此解决方案中(如 jpmc26 所说),您将始终在当前目录中创建一个新目录,因此您可能需要在调用 unzip
之前设置当前目录
对于那些想要使用 Shell.Application.Namespace.Folder.CopyHere() 并希望在复制时隐藏进度条或使用更多选项的人,文档在此处:
https://docs.microsoft.com/en-us/windows/desktop/shell/folder-copyhere
要使用 powershell 并隐藏进度条并禁用确认,您可以使用如下代码:
# We should create folder before using it for shell operations as it is required
New-Item -ItemType directory -Path "C:\destinationDir" -Force
$shell = New-Object -ComObject Shell.Application
$zip = $shell.Namespace("C:\archive.zip")
$items = $zip.items()
$shell.Namespace("C:\destinationDir").CopyHere($items, 1556)
在 Windows 核心版本上使用 Shell.Application 的限制:
https://docs.microsoft.com/en-us/windows-server/administration/server-core/what-is-server-core
在 Windows 核心版本上,默认情况下未安装 Microsoft-Windows-Server-Shell-Package,因此 shell.applicon 将不起作用。
注意:以这种方式提取档案需要很长时间,并且会减慢 windows gui
function unzip {
param (
[string]$archiveFilePath,
[string]$destinationPath
)
if ($archiveFilePath -notlike '?:\*') {
$archiveFilePath = [System.IO.Path]::Combine($PWD, $archiveFilePath)
}
if ($destinationPath -notlike '?:\*') {
$destinationPath = [System.IO.Path]::Combine($PWD, $destinationPath)
}
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$archiveFile = [System.IO.File]::Open($archiveFilePath, [System.IO.FileMode]::Open)
$archive = [System.IO.Compression.ZipArchive]::new($archiveFile)
if (Test-Path $destinationPath) {
foreach ($item in $archive.Entries) {
$destinationItemPath = [System.IO.Path]::Combine($destinationPath, $item.FullName)
if ($destinationItemPath -like '*/') {
New-Item $destinationItemPath -Force -ItemType Directory > $null
} else {
New-Item $destinationItemPath -Force -ItemType File > $null
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $destinationItemPath, $true)
}
}
} else {
[System.IO.Compression.ZipFileExtensions]::ExtractToDirectory($archive, $destinationPath)
}
}
使用:
unzip 'Applications\Site.zip' 'C:\inetpub\wwwroot\Site'
$archive
和 $archiveFile
ForEach
循环处理位于 $filepath
变量中的每个 ZIP 文件
foreach($file in $filepath)
{
$zip = $shell.NameSpace($file.FullName)
foreach($item in $zip.items())
{
$shell.Namespace($file.DirectoryName).copyhere($item)
}
Remove-Item $file.FullName
}
不定期副业成功案例分享
$PSVersionTable.PSVersion
确定您正在运行的 PowerShell 版本。OutputPath
已更改为DestinationPath
(参考 msdn.microsoft.com/powershell/reference/5.1/…)Expand-Archive -Path .\a.zip -DestinationPath .
等相对路径Expand-Archive
和Compress-Archive
要求存档文件扩展名为.zip
,而基于[System.IO.Compression.ZipFile]
的解决方案则不需要。