news 2026/9/27 21:17:30

Squirrel.Windows NuGet 包元数据完全指南:Id、Title、Version、IconUrl 与 Language 的实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Squirrel.Windows NuGet 包元数据完全指南:Id、Title、Version、IconUrl 与 Language 的实战解析
  • 开发工具

【免费下载链接】Squirrel.Windows

An installation and update framework for Windows desktop apps

项目地址:https://gitcode.com/gh_mirrors/sq/Squirrel.Windows
点击查看免费下载

导读

Squirrel.Windows 是一套面向 Windows 桌面应用的安装与更新框架,它在生成安装程序(Setup.exe)、创建桌面/开始菜单快捷方式以及注册 Windows "程序和功能"(Programs and Features)卸载条目时,会同时从应用 EXE 的版本资源和 NuGet 包的元数据(nuspec)中提取信息。本文以官方文档 docs/using/nuget-package-metadata.md 为主体,逐字段讲解Id、Title、Version、IconUrl、Language五项元数据的作用、取值来源与注意事项,并结合仓库源码揭示这些字段在安装、卸载与打包链路中的真实调用关系,帮助你正确配置 nuspec,避免踩坑。

一、元数据从何而来:EXE 与 nuspec 的"双输入"模型

Squirrel 的安装与卸载 UI 所需信息有两个来源(见 nuget-package-metadata.md):

  1. 应用的 EXE 文件:主要指通过rcedit.exe等工具写入 PE 资源的版本信息(CompanyName、FileDescription、ProductName 等)。在 src/Update/Program.cs 的setPEVersionInfoAndIcon方法中,--releasify流程会用rcedit.exe将 nuspec 中的authors、description、summary、copyright、version等数据回写到 EXE 资源中。
  2. NuGet 包元数据(nuspec):打包时由 nuspec 的<metadata>节点提供,Squirrel 运行期通过 NuGet 的ZipPackage读取(参见 src/Squirrel/ReleaseEntry.cs 中GetIconUrl对zp.IconUrl的读取)。

两个输入互为补充,但 nuspec 元数据是"主干",本文重点讨论后者。

二、Id:应用标识,决定安装目录与发布包文件名

Id是应用在 Squirrel 体系中的唯一标识,直接影响两个关键产物:

  • 发布包文件名:--releasify生成的包命名为<Id>-<Version>-full.nupkg与<Id>-<Version>-delta.nupkg。该命名逻辑在 src/Squirrel/ReleasePackage.cs 中实现:
    return String.Format("{0}-{1}-full.nupkg", zp.Id, zp.Version);

    例如Id = MyApp、Version = 1.0.0时,生成MyApp-1.0.0-full.nupkg。

  • 本地安装目录:应用被安装到%LocalAppData%\<Id>目录(如%LocalAppData%\MyApp),对应官方文档 docs/using/naming.md 中的 "Local Install location" 一节。

⚠️ 命名警告(issue #523):Id严禁包含空格和点(.)。空格与点会在包名解析(src/Squirrel/ReleaseEntry.cs 用正则^([\w-]+)-\d+\..+\.nupkg$解析PackageName)、目录创建、快捷方式命名等多个环节引发问题。另外在 src/Squirrel/UpdateManager.ApplyReleases.cs 中,Squirrel 用com.squirrel.{Id}.{exeName}生成 AppUserModelID 时会显式Replace(" ", "")去除空格,可见空格是需要规避的字符。

三、Title:Windows 卸载程序中显示的应用名

Title用于Windows 应用程序卸载程序(Programs and Features)中显示的应用名称,也就是上图中 "Name" 列的内容。源码层面的证据位于 src/Squirrel/UpdateManager.InstallHelpers.cs,写入卸载注册表的DisplayName取值为:

new { Key = "DisplayName", Value = zp.Title ?? zp.Description ?? zp.Summary },

即优先使用Title,缺失时依次回退到Description、Summary。同时 src/Squirrel/UpdateManager.ApplyReleases.cs 的linkTargetForVersionInfo显示,快捷方式名称(.lnk)的命名优先级为:EXE 的ProductName→ 包Title→ EXE 的FileDescription→ EXE 文件名,Title在其中占据第二顺位(完整优先级见 docs/using/naming.md)。

四、Version:发布包版本与卸载条目版本号

Version的取值来自Properties\AssemblyInfo.cs(即程序集版本,打包时写入 nuspec 的<version>节点),其作用包括:

  • 发布包文件名中的版本段:如MyApp-1.0.0-full.nupkg中的1.0.0(与Id一节同理,见 src/Squirrel/ReleasePackage.cs)。
  • Windows 卸载程序中的版本号:上图中 "Version" 列的内容。写入卸载注册表的DisplayVersion由zp.Version.ToString()直接生成(src/Squirrel/UpdateManager.InstallHelpers.cs)。

版本号同时会被回写到 EXE 资源(--set-file-version/--set-product-version,见 src/Update/Program.cs),确保资源管理器中的"文件版本/产品版本"与卸载条目一致。

五、IconUrl:快捷方式与卸载程序图标(安装时获取!)

IconUrl是图标的 URL,用于:

  • 桌面/开始菜单快捷方式图标;
  • Windows 卸载程序(Programs and Features)中该应用的图标(注册表DisplayIcon项)。

重要约束:IconUrl必须指向一个.ico(Icon)文件才能正确工作;且图标是在安装时从该 URL 获取,而非打包时(来源:issue #745)。

源码完整还原了这一流程(src/Squirrel/UpdateManager.InstallHelpers.cs):

if (zp.IconUrl != null && !File.Exists(targetIco)) { using (var wc = Utility.CreateWebClient()) { await wc.DownloadFileTaskAsync(zp.IconUrl, targetPng); using (var fs = new FileStream(targetIco, FileMode.Create)) { if (zp.IconUrl.AbsolutePath.EndsWith("ico")) { var bytes = File.ReadAllBytes(targetPng); fs.Write(bytes, 0, bytes.Length); // 直接拷贝 .ico } else { using (var bmp = (Bitmap)Image.FromFile(targetPng)) using (var ico = Icon.FromHandle(bmp.GetHicon())) { ico.Save(fs); // 其他格式临时转 .ico } } key.SetValue("DisplayIcon", targetIco, RegistryValueKind.String); } } }

运行期读取 IconUrl 的入口是 src/Squirrel/ReleaseEntry.cs 的GetIconUrl,它直接从ZipPackage.IconUrl取值。需要注意:安装机在安装那一刻必须能访问该 URL;若下载失败,Squirrel 只记录一条日志("Couldn't write uninstall icon, don't care")而不会中断安装(src/Squirrel/UpdateManager.InstallHelpers.cs),因此建议将图标托管在稳定可达的地址上。

六、Language:非英文字符的代码页支持

Language字段用于修改代码页(codepage),以支持非英文字符。未设置时默认为 1252(Windows-1252,西文 Latin-1 代码页)。

其实现位于 src/Update/Program.cs 的createMsiPackage中,nuspec 的language会被解析为对应的 ANSI 代码页,并填入 WiX MSI 模板的Codepage占位符:

var culture = CultureInfo.GetCultureInfo(package.Language ?? "").TextInfo.ANSICodePage; // templateData["Codepage"] = $"{culture}";

也就是说,若应用界面/安装文本包含非英文(如中文、日文、西里尔文等),应在 nuspec 中显式设置language为对应的文化名称(如zh-CN、ja-JP),否则安装程序可能按默认 1252 代码页处理导致乱码。此外在卸载注册表条目中,Squirrel 固定写入LanguageDWORD 值为0x0409(en-US 的 LCID,见 src/Squirrel/UpdateManager.InstallHelpers.cs)。

七、实战:一份完整的 nuspec 配置示例

综合以上字段,一个规范的 nuspec<metadata>节点应如下配置(参考仓库测试夹具 test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0.nuspec 的结构扩展):

<?xml version="1.0"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MyApp</id> <!-- 无空格、无点 --> <version>1.0.0</version> <!-- 与 AssemblyInfo 版本一致 --> <title>My App</title> <!-- 卸载程序显示名 --> <authors>MyCompany</authors> <!-- 写入卸载条目 Publisher --> <owners>MyCompany</owners> <description>My desktop application.</description> <summary>Short summary for file properties.</summary> <releaseNotes>What changed in this release.</releaseNotes> <language>zh-CN</language> <!-- 非英文场景必配,默认 1252 --> <iconUrl>https://example.com/app.ico</iconUrl> <!-- 必须 .ico,安装时下载 --> <requireLicenseAcceptance>false</requireLicenseAcceptance> </metadata> <files> <file src="lib\net45\MyApp.exe" target="lib\net45\MyApp.exe" /> </files> </package>

配套补充(写入卸载条目的其他字段,src/Squirrel/UpdateManager.InstallHelpers.cs):

注册表项取值来源
DisplayNameTitle??Description??Summary
DisplayVersionVersion
PublisherAuthors(逗号拼接)
DisplayIcon安装时从IconUrl下载的app.ico
InstallLocation%LocalAppData%\<Id>
URLUpdateInfoProjectUrl(如配置)
Language固定0x0409

八、常见问题与最佳实践小结

  1. Id 千万别带空格和点:否则发布包命名、安装目录、AppUserModelID、包名解析都会出问题(issue #523)。
  2. Title 缺失时卸载程序会"降级"显示:按Title → Description → Summary回退,建议至少补齐Description。
  3. IconUrl 必须是 .ico 且安装期可访问:Squirrel 在安装时下载图标并缓存在应用根目录app.ico;URL 不可达不会中断安装,但卸载程序将无图标。
  4. 非英文应用务必配置language:不配置时回退到 1252 代码页,可能造成安装文本乱码。
  5. 版本号保持 nuspec 与 AssemblyInfo 一致:二者同时影响发布包文件名、卸载条目DisplayVersion与 EXE 资源版本。

参见

  • Naming Conventions(命名约定总览):从 EXE 资源、nuspec 元数据到快捷方式/安装目录/卸载条目命名规则的完整优先级链。
  • Update Manager 安装辅助实现:卸载注册表条目的完整写入逻辑。
  • 打包/发布流程:--releasify如何消费上述元数据生成 Setup.exe 与发布包。
  • 开发工具

【免费下载链接】Squirrel.Windows

An installation and update framework for Windows desktop apps

项目地址:https://gitcode.com/gh_mirrors/sq/Squirrel.Windows
点击查看免费下载
上一篇:AMD ROCm 7.2.3环境搭建:运行DeepSeek-V4-Flash-NVFP4的系统要求与依赖安装
下一篇:Windows版微信QQ消息防撤回完整教程:告别错过重要信息的烦恼

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 21:07:38

mybatis中的sql映射文件(1)—resultType

目录0.前言1.resultType解析1.1.基本类型举例:1.2JavaBean类型1.3List类型1.4Map类型0.前言 mybaits中sql映射文件是一个xml文件&#xff0c;里面记录的和数据库交互的各种信息&#xff0c;相当于sql语句&#xff0c;在写这些语句的时候&#xff0c;遇到很多不同的参数&#x…

作者头像 李华