You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

针对遗留服务器:如何在PowerShell v2.0中压缩文件为ZIP?

兄弟,我太懂这种遗留系统的痛点了!Compress-Archive确实是PowerShell 5.0才新增的cmdlet,在v2.0里完全没法用。不过不用慌,我们有两种系统自带的方案,既能实现ZIP压缩,还能满足你原来的-Update需求——也就是覆盖更新现有压缩包里的文件。

方案1:用Windows Shell组件(强烈推荐,零依赖)

这个方法靠Windows自带的Shell.Application COM对象实现,几乎所有Windows系统都支持,不需要装任何额外软件,完美适配v2.0。

实现单个文件压缩+更新ZIP的代码

# 先定义你的路径,替换成实际值
$rootFolder = "C:\你的文件夹路径"
$sourceFile = Join-Path $rootFolder "temp-file.csv"
$destinationZip = Join-Path $rootFolder "temp-file.zip"

# 如果ZIP文件不存在,先创建一个空的(必须写ZIP文件头,否则Shell识别不了)
if (-not (Test-Path $destinationZip)) {
    $null = New-Item -Path $destinationZip -ItemType File -Force
    # 写入ZIP格式的文件头
    $zipHeader = [byte[]]@(80, 75, 5, 6) + [byte[]]::CreateInstance([byte], 18)
    [System.IO.File]::WriteAllBytes($destinationZip, $zipHeader)
}

# 调用Shell组件处理压缩
$shell = New-Object -ComObject Shell.Application
$zipContainer = $shell.NameSpace((Resolve-Path $destinationZip).Path)
$fileToCompress = $shell.NameSpace((Resolve-Path $sourceFile).Path).Items()

# 复制文件到ZIP,参数4代表覆盖现有文件(对应原来的-Update)
$zipContainer.CopyHere($fileToCompress, 4)

# 注意:CopyHere是异步执行的,加个短暂等待确保操作完成(大文件可以延长时间)
Start-Sleep -Seconds 2

# 用完释放COM对象,避免内存泄漏
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null

这里的关键是CopyHere的参数4,它的作用就是覆盖ZIP里已有的同名文件,完全匹配你原来-Update的需求。

方案2:用.NET Framework(需.NET 4.5+)

如果你的服务器已经安装了.NET Framework 4.5或更高版本(比如Windows Server 2012及以上默认自带,2008 R2需要手动升级),可以用.NET的压缩类来实现,这种方法是同步执行的,不需要等待,逻辑更清晰。

实现代码

# 加载.NET压缩相关的程序集
Add-Type -AssemblyName System.IO.Compression.FileSystem

# 定义路径
$rootFolder = "C:\你的文件夹路径"
$sourceFile = Join-Path $rootFolder "temp-file.csv"
$destinationZip = Join-Path $rootFolder "temp-file.zip"

# 打开ZIP文件(不存在则创建),使用Update模式
$zipMode = [System.IO.Compression.ZipArchiveMode]::Update
using ($zipArchive = [System.IO.Compression.ZipFile]::Open($destinationZip, $zipMode)) {
    # 检查ZIP里是否已有目标文件,有的话先删除
    $existingEntry = $zipArchive.GetEntry((Split-Path $sourceFile -Leaf))
    if ($existingEntry) {
        $existingEntry.Delete()
    }
    # 添加新文件到ZIP
    [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
        $zipArchive,
        $sourceFile,
        (Split-Path $sourceFile -Leaf)
    )
}

这个方法不需要处理异步等待的问题,代码更严谨,但前提是服务器必须有.NET 4.5+,如果是特别老的系统可能不适用。

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

火山引擎 最新活动