开发工具【免费下载链接】Squirrel.WindowsAn installation and update framework for Windows desktop apps项目地址https://gitcode.com/gh_mirrors/sq/Squirrel.Windows点击查看免费下载对生产环境发布的 Windows 桌面应用来说使用有效代码签名证书为安装程序签名是发布前最重要的工作之一正确的签名既能让 IE SmartScreen 和杀毒软件给出更高的信任评级也能避免用户在安装时看到令人生畏的警告对话框。本文基于 Squirrel.Windows 仓库中的 application-signing.md 官方文档结合 src/Update/Program.cs 等源码实现完整讲解如何获取证书、通过-n / --signWithParams参数将签名参数透传给signtool.exe以及 Squirrel 自动为应用内全部可执行文件 最终 Setup.exe双重签名的底层机制。读完本文你将能够在自己项目的发布流程中一步到位地配置代码签名包括在 Visual Studio 构建打包MSBuild场景下正确处理 XML 转义。为什么必须为应用签名Squirrel 官方文档明确强调用有效代码签名证书为安装程序签名是生产应用发布前最重要的事情之一。其影响体现在两个方面SmartScreen 信任Windows 自带的 IE SmartScreen 会为签名正确的应用累积大量信任分值从而减少用户安装时遇到的Windows 已保护你的电脑之类的红色/黄色警告。杀毒软件信任主流病毒扫描软件同样会对签名正确的可执行文件给出更高信任评级降低误报率减少用户被吓退的概率。未签名的安装程序很容易被 SmartScreen 拦截、被杀软标记直接导致用户流失。因此签名不是可选优化而是进入生产发布的基本要求。第一步获取代码签名证书Squirrel 文档建议获取Windows Error ReportingWER兼容的代码签名证书。这类证书通常来自受信任的 CA证书颁发机构购买后你会得到一个.pfx证书文件以及与之对应的私钥密码。.pfx文件需要妥善保管后续的signtool.exe签名命令会直接引用它。拿到证书文件后你还需要一个可用的signtool.exe。Squirrel 在打包时优先使用随包发布的 signtool在 src/Squirrel.nuspec 中可以看到signtool.exe被打进 NuGet 包的tools目录同时 src/Update/Update.csproj 也配置了CopyToOutputDirectoryPreserveNewest确保构建产物中始终带有该工具。签名参数入口-n / --signWithParamsSquirrel 的命令行工具Squirrel.exe即 Update 工程通过-n长参数--signWithParams接收签名参数。在 src/Update/StartupOption.cs 中可以看到它的定义{ n|signWithParams, Sign the installer via SignTool.exe with the parameters given, v signingParameters v },该参数在 squirrel-command-line.md 中的帮助说明为-n, --signWithParamsVALUE Sign the installer via SignTool.exe with the parameters given它的语义是把你原本要传给signtool.exe sign的一整串参数原样接收下来由 Squirrel 在打包流程中拼接成完整的签名命令并执行。从 src/Update/Program.cs 的signPEFile实现可以看到实际调用方式var processResult await Utility.InvokeProcessAsync(exe, String.Format(sign {0} \{1}\, signingOpts, exePath), CancellationToken.None);也就是最终执行的命令形如signtool.exe sign 你的参数 待签名文件。这正是文档中-n的参数就是你原本会传给signtool.exe sign的参数这句话的源码级印证。端到端示例命令官方文档给出的完整调用示例在 Package Manager Console 中执行如下PM Squirrel --releasify MyApp.1.0.0.nupkg -n /a /f CodeCert.pfx /p MySecretCertPassword /fd sha256 /tr http://timestamp.digicert.com /td sha256逐项拆解这条命令片段含义Squirrel --releasify MyApp.1.0.0.nupkg以给定 NuGet 包生成或更新 releases 目录这是 Squirrel 打包的核心命令-n ...声明要启用签名并把引号内参数透传给signtool.exe sign/a自动选择最佳证书从当前证书存储中挑选/f CodeCert.pfx指定用于签名的证书文件路径/p MySecretCertPassword证书私钥密码/fd sha256指定文件摘要算法为 SHA-256现代签名推荐值/tr http://timestamp.digicert.comRFC 3161 时间戳服务器 URL保证证书过期后签名依然有效/td sha256指定时间戳摘要算法为 SHA-256与/fd sha256配套使用其中/tr与/td配合实现了带时间戳的签名即使未来证书过期已签名的安装包仍会被 Windows 信任。/fd sha256则确保签名摘要算法不是已不推荐的 SHA-1。Squirrel 签名的范围不止 Setup.exe文档强调Squirrel 让签名变得简单因为它会为应用中所有可执行文件以及最终生成的 Setup.exe一并签名。这一承诺在 src/Update/Program.cs 的Releasify流程中有完整的实现支撑签名动作覆盖以下几个阶段包内全部 PE 映像在CreateReleasePackage的contentsPostProcessHook中Squirrel 递归遍历解包目录下所有FileIsLikelyPEImage的文件即所有可能的 PE 可执行映像逐一调用signPEFile签名。已签名文件自动跳过签名前会先调用isPEFileSigned检测若已签名则跳过避免重复签名导致文件损坏。该检测基于 src/Update/AuthenticodeTools.cs 封装的 Win32WinVerifyTrustAPIWintrust.dll只有验证通过才视为已签名。嵌入的 Update.exeSquirrel 会把Update.exe、.nupkg、RELEASES等打包成嵌入 Setup.exe 的 zip。在createSetupEmbeddedZipsrc/Update/Program.cs中zip 内的全部.exe包括 Update.exe都会在压缩前完成签名源码注释明确说明这是为了让病毒扫描器不会误以为我们在偷梁换柱。最终 Setup.exezip 写入 Setup.exe 模板并设置版本信息与图标后若提供了signingOpts会对最终 Setup.exe 再执行一次签名src/Update/Program.cs。MSI 包如生成Releasify默认会生成 MSI生成的.msi同样会被签名src/Update/Program.cs。也就是说一条-n参数换来的是包内所有可执行文件 Update.exe Setup.exe 可选 MSI的全链路签名这正是文档所强调的让签名变简单的完整含义。signtool.exe 的定位机制与密码保护签名命令依赖signtool.exeSquirrel 的查找顺序src/Update/Program.cs为当前目录下的.\signtool.exe当前程序集所在目录即Update.exe/Squirrel.exe所在目录中的signtool.exe沿系统PATH环境变量查找能找到就用。由于signtool.exe已随 Squirrel 包分发到tools目录见 src/Squirrel.nuspec大多数场景下无需手动安装 Windows SDK 即可完成签名。另外源码还对安全性做了细节处理当签名失败抛出异常时src/Update/Program.cs 会用正则把命令中的/p 密码替换为/p ********确保证书密码不会明文泄露到日志或控制台错误信息中。在 Visual Studio 构建打包中配置签名如果你使用 Visual Studio 构建打包流程详见 visual-studio-packaging.md需要特别注意XML 中的引号转义。官方文档给出了在.csproj的AfterBuildTarget 中集成的完整示例Target NameAfterBuild Condition $(Configuration) Release GetAssemblyIdentity AssemblyFiles$(TargetPath) Output TaskParameterAssemblies ItemNamemyAssemblyInfo / /GetAssemblyIdentity Exec Commandnuget pack MyApp.nuspec -Version %(myAssemblyInfo.Version) -Properties ConfigurationRelease -OutputDirectory $(OutDir) -BasePath $(OutDir) / !-- Notice the use of quot; rather than after the \n flag. For the password to contain spaces we need to double-quot; the string. -- Exec Commandsquirrel --releasify $(OutDir)MyApp.$([System.Version]::Parse(%(myAssemblyInfo.Version)).ToString(3)).nupkg -n quot;/a /f .\CertificateInProjectFolder.pfx /p quot;quot;CERTIFICATE PASSWORDquot;quot; /fd sha256 /tr http://timestamp.digicert.com /td sha256quot; / /Target这里有两个关键转义规则也是官方文档重点提醒的坑包裹-n参数的引号必须写成 XML 安全的quot;。MSBuild 的Exec属性值是 XML直接写会被 XML 解析器当作属性定界符导致命令解析失败。证书密码若含空格需要双重引号由于整条命令本身已处于一对引号中密码外层的引号要写成quot;quot;PASSWORDquot;quot;经 XML 与命令行两层解析后还原为/p PASSWORD的语义保证带空格的密码被正确视为一个整体参数。示例中CERTIFICATE PASSWORD就演示了这一写法。顺带一提该 Target 中nuget pack使用-Version %(myAssemblyInfo.Version)从程序集版本自动生成 NuGet 包版本squirrel --releasify则消费$(OutDir)下对应版本的.nupkg只需把-n参数追加到--releasify命令末尾即可让每次 Release 构建自动产出已签名的 Setup.exe。若构建时报squirrel is not recognized as an internal or external command9009说明squirrel.exe不在 PATH 中需要在Exec Command中改用squirrel.exe的完整路径。小结围绕-n / --signWithParamsSquirrel.Windows 把为安装包签名这件事收敛成了一条命令参数你只需提供证书文件、密码和首选摘要/时间戳算法Squirrel 就会在Releasify全流程中自动签名应用内全部可执行文件、嵌入的 Update.exe、最终 Setup.exe 以及可选的 MSI。配合 WER 兼容的代码签名证书即可显著降低 SmartScreen 与杀毒软件的拦截概率让用户获得顺滑的安装体验。在 Visual Studio 构建集成时牢记 XML 的quot;与密码双重引号规则即可规避绝大多数配置陷阱。更多相关内容可继续阅读Squirrel 命令行参考Squirrel --releasify的全部命令与选项Visual Studio 构建打包将 Squirrel 打包集成进构建流程文档目录返回全部使用文档索引赞分享开发工具【免费下载链接】Squirrel.WindowsAn installation and update framework for Windows desktop apps项目地址https://gitcode.com/gh_mirrors/sq/Squirrel.Windows点击查看免费下载相关推荐Bun代码签名macOS可执行文件的安全认证Bun代码签名macOS可执行文件的安全认证 引言为什么macOS应用需要代码签名 在macOS生态系统中代码签名Code Signing是一项至关语言运行时后端开发工具包管理器前端构建测试Tink Java 数字签名实战用 PublicKeySign / PublicKeyVerify 对文件签名与验签Tink Java 数字签名实战用 PublicKeySign / PublicKeyVerify 对文件签名与验签 导读 本文以 Tink 仓库中的 Jav密码学GoReleaser 二进制签名指南用 binary_signs 在归档前签名每个可执行文件GoReleaser 二进制签名指南用 binary_signs 在归档前签名每个可执行文件 GoReleaser 从 v2.2 起提供了 binary_si开发工具CI/CD构建工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
