74 lines
2.5 KiB
PowerShell
74 lines
2.5 KiB
PowerShell
param(
|
||
[Parameter(Mandatory = $true)][string]$Path
|
||
)
|
||
|
||
# 给构建产物加 Authenticode 签名。
|
||
#
|
||
# 下载提示"有风险/有病毒"的根源是 EXE 没有数字签名、也没有下载信誉,
|
||
# SmartScreen 和浏览器会拦截一切无签名的新程序。买到代码签名证书后:
|
||
# - 证书在系统证书库里: 设 WECOM_CODESIGN_THUMBPRINT=<证书指纹>
|
||
# - 证书是 PFX 文件: 设 WECOM_CODESIGN_PFX=<pfx 路径>,
|
||
# 密码放 WECOM_CODESIGN_PFX_PASSWORD
|
||
# 两者都没设置时本脚本直接跳过,不影响构建。
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
$thumbprint = ([string]$env:WECOM_CODESIGN_THUMBPRINT).Trim()
|
||
$pfxPath = ([string]$env:WECOM_CODESIGN_PFX).Trim()
|
||
if (-not $thumbprint -and -not $pfxPath) {
|
||
Write-Output ("Code signing skipped (no certificate configured): " + [System.IO.Path]::GetFileName($Path))
|
||
exit 0
|
||
}
|
||
|
||
if (-not (Test-Path -LiteralPath $Path)) {
|
||
throw ("Cannot sign, file not found: " + $Path)
|
||
}
|
||
|
||
function Find-SignTool {
|
||
$fromPath = Get-Command signtool.exe -ErrorAction SilentlyContinue
|
||
if ($fromPath) { return $fromPath.Source }
|
||
$kitRoots = @(
|
||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin",
|
||
"$env:ProgramFiles\Windows Kits\10\bin"
|
||
)
|
||
foreach ($root in $kitRoots) {
|
||
if (-not (Test-Path -LiteralPath $root)) { continue }
|
||
$candidate = Get-ChildItem -Path $root -Recurse -Filter signtool.exe -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.FullName -match "\\x64\\" } |
|
||
Sort-Object FullName -Descending |
|
||
Select-Object -First 1
|
||
if ($candidate) { return $candidate.FullName }
|
||
}
|
||
return $null
|
||
}
|
||
|
||
$signtool = Find-SignTool
|
||
if (-not $signtool) {
|
||
throw "Signing certificate is configured but signtool.exe was not found. Install the Windows 10/11 SDK (Signing Tools component)."
|
||
}
|
||
|
||
$timestampUrl = ([string]$env:WECOM_CODESIGN_TIMESTAMP_URL).Trim()
|
||
if (-not $timestampUrl) { $timestampUrl = "http://timestamp.digicert.com" }
|
||
|
||
$arguments = @("sign", "/fd", "SHA256", "/td", "SHA256", "/tr", $timestampUrl)
|
||
if ($thumbprint) {
|
||
$arguments += @("/sha1", $thumbprint)
|
||
}
|
||
else {
|
||
$arguments += @("/f", $pfxPath)
|
||
$pfxPassword = ([string]$env:WECOM_CODESIGN_PFX_PASSWORD).Trim()
|
||
if ($pfxPassword) { $arguments += @("/p", $pfxPassword) }
|
||
}
|
||
$arguments += $Path
|
||
|
||
& $signtool @arguments
|
||
if ($LASTEXITCODE -ne 0) {
|
||
throw ("Code signing failed: " + $Path)
|
||
}
|
||
|
||
& $signtool verify /pa $Path
|
||
if ($LASTEXITCODE -ne 0) {
|
||
throw ("Signature verification failed: " + $Path)
|
||
}
|
||
Write-Output ("Signed: " + $Path)
|