抱歉,这个问题分散在互联网上,但我还没有找到一个满意的答案,只使用Powershell 2.0(带有.NET v3.5(-没有外部库或程序
我使用以下代码从ZipFile.zip
(无论log.txt
的位置如何(中提取log.txt
$Destination = (new-object -com shell.application).NameSpace('C:ZipExtractDir')
$ZipFile = (new-object -com shell.application).NameSpace('C:ZipFile.zip')
$Destination.CopyHere(($Zipfile.Items() | where-object {$_.Name -like '*log.txt'}), 1044)
- 如果
log.txt
在根目录log.txt
中则有效 - 如果
log.txt
在子目录Subfolderlog.txt
中,则失败 - 如果引用文本(.zip(路径,则失败
{$_.Name -Like '*Subfolderlog.txt'}
(双引号和单引号都失败( - 尝试使用
-eq
-like
-contains
''
""
$_.FullName
我很确定我过滤错误了——有人能帮我处理这段代码吗?这样它也能解析子目录吗?
与您已经做的类似,您可以像这样设置Shell.Application
名称空间。然后,您可以将提取的目录复制到目标路径。
$zipFilePath = "Zipfile.zip"
$destinationPath = "C:UsersPublicDownloads"
$zipfile = (New-Object -Com Shell.Application).NameSpace($zipFilePath)
$destination = (New-Object -Com Shell.Application).NameSpace($destinationPath)
$destination.CopyHere($zipfile.Items())
然后为了列出log.txt
文件,我们可以用Join-Path
构造完整的提取路径。这基本上只是将来自System.IO.Path.GetFileNameWithoutExtension()
的zip文件名附加到目标路径。然后只需使用Get-ChildItem
通过-Recurse
和-Filter
开关递归地列出文件。
$extractedPath = Join-Path -Path $destinationPath -ChildPath ([System.IO.Path]::GetFileNameWithoutExtension($zipFilePath))
Get-ChildItem -Path $extractedPath -Filter log.txt -Recurse
为了在PowerShell 2.0中测试这一点,我们可以将-version 2
与powershell.exe
:一起使用
powershell.exe -version 2 .test.ps1
更新
如果你想在提取之前检查文件,你需要自己递归目录。下面是如何做到这一点的演示。
function New-ZipChildRootFolder
{
param
(
[string]$DestinationPath,
[string]$ZipFileName
)
$folderPath = Split-Path -Path $ZipFileName -Leaf
$destination = (New-Object -ComObject Shell.Application).NameSpace($DestinationPath)
$destination.NewFolder($folderPath)
}
function Get-ZipChildItems
{
param
(
[string]$ZipFilePath,
[string]$DestinationPath
)
$zipfile = (New-Object -ComObject Shell.Application).NameSpace($ZipFilePath)
$zipFileName = [System.IO.Path]::GetFileNameWithoutExtension($ZipFilePath)
Write-Output "Create root zip folder : $zipFileName"
New-ZipChildRootFolder -DestinationPath $DestinationPath -ZipFileName $zipFileName
foreach ($item in $zipFile.items())
{
Get-ZipChildItemsRecurse -Items $item -DestinationPath $DestinationPath -ZipFileName $zipFileName
}
}
function Get-ZipChildItemsRecurse
{
param
(
[object]$Items,
[string]$DestinationPath,
[string]$ZipFileName
)
foreach ($file in $Items.getFolder.Items())
{
if ($file.IsFolder -eq $true)
{
Write-Output "Creating folder : $($file.Path)"
New-ZipChildFolder -Folder $file -DestinationPath $DestinationPath -ZipFileName $ZipFileName
Get-ZipChildItemsRecurse -Items $file -DestinationPath $DestinationPath -ZipFileName $ZipFileName
}
else
{
$filename = Split-Path -Path $file.Path -Leaf
if ($filename -eq "log.txt")
{
Write-Output "Copying file : $($file.Path)"
New-ZipChildFile -File $file -DestinationPath $DestinationPath -ZipFileName $ZipFileName
}
}
}
}
function New-ZipChildFile
{
param
(
[object]$File,
[string]$DestinationPath,
[string]$ZipFileName
)
$destination = New-Object -ComObject Shell.Application
$items = $File.Path.Split("")
$zipRootIndex = [array]::IndexOf($items, $ZipFileName)
$path = $items[$zipRootIndex..($items.Length - 2)] -join ""
$fullPath = Join-path -Path $DestinationPath -ChildPath $path
$destination.NameSpace($fullPath).CopyHere($File)
}
function New-ZipChildFolder
{
param
(
[object]$Folder,
[string]$DestinationPath,
[string]$ZipFileName
)
$destination = New-Object -ComObject Shell.Application
$items = $Folder.Path.Split("")
$zipRootIndex = [array]::IndexOf($items, $ZipFileName)
$folders = $items[$zipRootIndex..($items.Length - 1)]
$currentFolder = $DestinationPath
foreach ($folder in $folders)
{
$destination.NameSpace($currentFolder).NewFolder($folder)
$currentFolder = Join-Path -Path $currentFolder -ChildPath $folder
}
}
用法:
$zipFilePath = "C:Zipfile.zip"
$destinationPath = "C:UsersPublicDownloads"
Get-ZipChildItems -ZipFile $zipFilePath -DestinationPath $destinationPath