You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell提取ZIP中文件版本与修改日期及定位问题求助

问题:从ZIP包提取二进制文件版本及SQL文件修改日期失败

问题背景

我需要从ZIP压缩包中的EXE、DLL提取文件版本,同时获取SQL文件的修改日期,但遇到了文件定位失败的问题:

  • 指定ZIP文件:$vipFile = Get-ChildItem -ErrorAction Stop -Path "C:\Patch_2029274.vip"
  • 目标SQL文件名:$file = 'Pulling%20AD_Domain_Stored%20Procedures_PullAD-sp.sql'

当前ReadFileContentFromArchive函数无法定位目标文件,原因是ZIP条目包含完整路径而非仅文件名。$zipReader的Entries内容如下:

Entries                                                                                                                                                                                                                                     Mode
-------                                                                                                                                                                                                                                     ----
{IDUDatabase_4.0.0.131/IDUDatabase/AD_Domain_Stored%20Procedures_DerivedRelations-sp.sql, IDUDatabase_4.0.0.131/IDUDatabase/Pulling%20AD_Domain_Stored%20Procedures_PullAD-sp.sql, IDUDatabase_4.0.0.131/filesSources.txt, vip.manifest...} Read

当前函数代码

function ReadFileContentFromArchive {
    param (
        [Parameter(Mandatory=$true)][string]$ZipFile,
        [Parameter(Mandatory=$true)][string]$TargetFile
    )

    #workaround because this fails: [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression') 
    #Add-Type -Path "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll"

    $zipReader = [System.IO.Compression.ZipFile]::OpenRead($zipFile)

    $zipEntry = $zipReader.GetEntry($targetFile)

}

调用方式:

$FileInfo = ReadFileContentFromArchive -ZipFile $vipFile -TargetFile $file

解决方案

1. 修复文件定位及功能实现

针对ZIP条目含完整路径的问题,通过提取文件名忽略路径来匹配目标文件,同时实现二进制文件版本提取和SQL文件修改日期获取的功能:

function ReadFileContentFromArchive {
    param (
        [Parameter(Mandatory=$true)][string]$ZipFile,
        [Parameter(Mandatory=$true)][string]$TargetFile
    )

    # PowerShell 5+默认已加载该程序集,若报错可取消下面注释
    # Add-Type -AssemblyName System.IO.Compression.FileSystem

    $zipReader = [System.IO.Compression.ZipFile]::OpenRead($zipFile)
    try {
        # 遍历ZIP条目,匹配文件名(忽略路径)
        $zipEntry = $zipReader.Entries | Where-Object { 
            [System.IO.Path]::GetFileName($_.FullName) -eq $TargetFile
        } | Select-Object -First 1

        if (-not $zipEntry) {
            Write-Error "目标文件 $TargetFile 在ZIP包中未找到"
            return $null
        }

        # 根据文件类型执行不同逻辑
        $fileExtension = [System.IO.Path]::GetExtension($zipEntry.FullName).ToLower()
        switch ($fileExtension) {
            '.sql' {
                # 直接返回ZIP条目的修改时间作为SQL文件的修改日期
                return [PSCustomObject]@{
                    FileType = 'SQL'
                    ModifyDate = $zipEntry.LastWriteTime
                    EntryFullPath = $zipEntry.FullName
                }
            }
            { $_ -in '.exe', '.dll' } {
                # 临时解压二进制文件到临时目录,提取版本信息后删除临时文件
                $tempFile = [System.IO.Path]::GetTempFileName()
                try {
                    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipEntry, $tempFile, $true)
                    $versionInfo = (Get-Item $tempFile).VersionInfo
                    return [PSCustomObject]@{
                        FileType = 'Binary'
                        FileVersion = $versionInfo.FileVersion
                        ProductVersion = $versionInfo.ProductVersion
                        ModifyDate = $zipEntry.LastWriteTime
                        EntryFullPath = $zipEntry.FullName
                    }
                }
                finally {
                    Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
                }
            }
            default {
                Write-Warning "不支持处理的文件类型:$fileExtension"
                return $null
            }
        }
    }
    finally {
        # 确保释放ZIP阅读器资源
        $zipReader.Dispose()
    }
}

2. 调用示例

$vipFile = Get-ChildItem -ErrorAction Stop -Path "C:\Patch_2029274.vip"
$file = 'Pulling%20AD_Domain_Stored%20Procedures_PullAD-sp.sql'
$FileInfo = ReadFileContentFromArchive -ZipFile $vipFile.FullName -TargetFile $file

# 查看结果
$FileInfo

关键说明

  • 使用[System.IO.Path]::GetFileName()提取ZIP条目的纯文件名,解决路径不一致导致的定位失败问题。
  • SQL文件无需解压,直接读取ZIP条目的LastWriteTime作为修改日期。
  • EXE/DLL文件临时解压到系统临时目录,提取版本信息后自动清理临时文件,避免磁盘占用。
  • 添加finally块确保ZIP阅读器资源被正确释放,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Bandit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:33:27