借助网络配置,控制Modbus工具的日志显示,避免卡死界面
智能大石头 authored at 2021-12-11 22:09:19
4.23 KiB
XCoder
<#
.SYNOPSIS
    把原生库打包为 zip,供以嵌入资源形式随程序集发布。

.DESCRIPTION
    原生 DLL 多为未压缩 PE 文件,zip 压缩率通常可达 3~8 倍。
    打包后由 ZipResourceExtractor 在运行时解压还原,可显著减小程序集体积。

    打包产物命名需与代码约定一致:
      · 单文件:{目录}.{文件名去扩展名}.zip,zip 内仅含该文件
               例:CAN\ZLG_CAN\zlgcan.dll -> CAN\ZLG_CAN\zlgcan.zip
      · 目录  :{目录名}.zip,zip 内含目录内全部文件(保留相对结构)
               例:CAN\ZLG_CAN\kerneldlls -> CAN\ZLG_CAN\kerneldlls.zip

.PARAMETER Target
    可选,指定要打包的目标(相对本脚本目录)。缺省打包全部已配置项。

.EXAMPLE
    .\pack_native_res.ps1

.EXAMPLE
    .\pack_native_res.ps1 -Target 'CAN\ZLG_CAN\kerneldlls'
#>
[CmdletBinding()]
param(
    [string]$Target
)

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

$root = $PSScriptRoot

# 待打包项:与 A1Lib.csproj 中的嵌入配置一一对应
$items = @(
    @{ Path = 'CAN\ZLG_CAN\zlgcan.dll';  Kind = 'file' }
    @{ Path = 'CAN\ZLG_CAN\kerneldlls';  Kind = 'dir'  }
    @{ Path = 'CAN\CX_CAN\ControlCAN.dll'; Kind = 'file' }
    @{ Path = 'CAN\PCAN\PCANBasic.dll';  Kind = 'file' }
)

function Get-ZipPath([string]$relPath, [string]$kind) {
    $full = Join-Path $root $relPath
    if ($kind -eq 'dir') {
        return "$full.zip"
    }
    # 单文件:同名但扩展名换成 .zip
    $dir  = Split-Path $full -Parent
    $base = [IO.Path]::GetFileNameWithoutExtension($full)
    return (Join-Path $dir "$base.zip")
}

function Write-Zip([string]$srcPath, [string]$kind, [string]$zipPath) {
    if (Test-Path $zipPath) { Remove-Item $zipPath -Force }

    if ($kind -eq 'dir') {
        # 目录:以目录内容为根,保留相对结构(解压后直接铺在目标目录下)
        Compress-Archive -Path (Join-Path $srcPath '*') -DestinationPath $zipPath -CompressionLevel Optimal
    }
    else {
        # 单文件:以文件名作为 zip 内的条目名
        Compress-Archive -Path $srcPath -DestinationPath $zipPath -CompressionLevel Optimal
    }
    return $zipPath
}

function Format-Size([long]$n) {
    if ($n -ge 1MB) { return ('{0:N2} MB' -f ($n / 1MB)) }
    if ($n -ge 1KB) { return ('{0:N1} KB' -f ($n / 1KB)) }
    return "$n B"
}

$results = @()

foreach ($it in $items) {
    $rel = $it.Path
    $kind = $it.Kind

    if ($Target -and ($rel -ne $Target)) { continue }

    $src = Join-Path $root $rel
    if (-not (Test-Path $src)) {
        Write-Warning "跳过(不存在): $rel"
        continue
    }

    # 源大小
    if ($kind -eq 'dir') {
        $rawSize = (Get-ChildItem $src -Recurse -File | Measure-Object -Property Length -Sum).Sum
        $fileCount = (Get-ChildItem $src -Recurse -File).Count
    }
    else {
        $rawSize = (Get-Item $src).Length
        $fileCount = 1
    }

    $zipPath = Get-ZipPath $rel $kind
    Write-Zip $src $kind $zipPath | Out-Null

    $zipSize = (Get-Item $zipPath).Length
    $ratio = if ($rawSize -gt 0) { $zipSize / $rawSize } else { 0 }

    $results += [pscustomobject]@{
        目标     = $rel
        类型     = $kind
        文件数   = $fileCount
        原始     = Format-Size $rawSize
        压缩后   = Format-Size $zipSize
        压缩率   = ('{0:P0}' -f $ratio)
        Zip      = [IO.Path]::GetFileName($zipPath)
        RawBytes = [long]$rawSize
        ZipBytes = [long]$zipSize
    }
}

if ($results.Count -eq 0) {
    Write-Host '没有可打包的目标。' -ForegroundColor Yellow
    return
}

$results | Select-Object 目标, 类型, 文件数, 原始, 压缩后, 压缩率 | Format-Table -AutoSize

$sumRaw = ($results | Measure-Object -Property RawBytes -Sum).Sum
$sumZip = ($results | Measure-Object -Property ZipBytes -Sum).Sum
$sumRatio = if ($sumRaw -gt 0) { $sumZip / $sumRaw } else { 0 }

Write-Host ''
Write-Host ('合计:{0} -> {1}(压缩率 {2:P0})' -f (Format-Size $sumRaw), (Format-Size $sumZip), $sumRatio) -ForegroundColor Green

Write-Host ''
Write-Host '说明:zip 与原始文件同时存在于源码目录时,A1Lib.csproj 只嵌入 zip。'
Write-Host '      原始文件保留供打包与排查使用,不参与编译。'