ClickOnce 是什么 - 从实务角度整理其原理、更新机制以及适用与不适用的场景
· 小村 豪 · Windows, 发布, ClickOnce, .NET, Windows开发
谈到 Windows 上 .NET 桌面应用的发布话题,在 MSI 和 MSIX 的阴影下,总会不起眼地反复出现一个名字,那就是 ClickOnce。
不过,如果在这里简单粗暴地
- 认为它是老技术所以不再使用
- 或者反过来,觉得它看起来简单,什么都能用 ClickOnce 解决
倾向于其中任何一种极端判断,大都会判断失误。
ClickOnce 并不是什么都能做的万能 installer。但另一方面,在社内业务用的 .NET 应用中,如果场景是 要发布给标准用户,并希望以低成本连更新一起运转,那么 ClickOnce 至今仍相当有力。
本文将以实务视角,配合较多的 Mermaid 图,整理 ClickOnce 究竟是什么、如何运作、优势何在,以及在哪些地方会显得力不从心。内容主要以 2026 年 4 月时点可确认的 Microsoft Learn 信息为前提。
图为概念图。在支持 Mermaid 的 Markdown 环境中会以图形方式显示。
目录
- 先说结论
- ClickOnce 是什么
- 构成 ClickOnce 的要素
- 从安装到启动的流程
- 更新机制
- ClickOnce 的优势
- 适用场景
- 不适用场景
- 实务中容易踩坑的地方
- 总结
- 相关文章
- 参考资料
1. 先说结论
如果用一句话概括 ClickOnce,那就是:一种按用户单位轻松发布 .NET Windows 桌面应用,并包含自动更新在内的发布技术。
适用的场景,例如以下这些情况。
- WinForms / WPF 等社内业务应用
- 想以标准用户身份安装
- per-user 发布已经足够
- 想拥有内置(built-in)更新能力
- 发布渠道只需网站或文件共享即可
反过来,如果有以下这类需求,最好从一开始就考虑别的方案,会更安全。
- 面向所有用户的 machine-wide install
- Windows service、driver、in-process shell extension、深度 COM 注册
- 需要 package identity
- 想掌控更新渠道、分阶段发布、自定义 rollback UX
- 作为 installer 需要深入 OS 的职责很重
总而言之,ClickOnce 是一种 在简单发布与简单更新方面很强,但不适合 OS 集成需求较重的项目 的方式。
先用一张图看清定位
flowchart TD
A["想发布 Windows 应用"]
B{"是否需要深度集成 OS"}
C["从 MSI / MSIX 方向考虑"]
D{"是 .NET 的 Windows 桌面应用,<br/>且 per-user 发布是否足够"}
E{"是否想发布给标准用户"}
F{"built-in 更新是否足够"}
G["ClickOnce 较为有力"]
H["也比较一下 xcopy / 自制 updater"]
A --> B
B -- 是 --> C
B -- 否 --> D
D -- 否 --> H
D -- 是 --> E
E -- 否 --> H
E -- 是 --> F
F -- 是 --> G
F -- 否 --> H
2. ClickOnce 是什么
ClickOnce 是 Microsoft 提供的一种 Windows 应用发布技术。官方说明将其定义为:一种可通过最少的用户操作完成安装与运行,并具备自我更新能力的 Windows 应用发布技术。
这里重要的是,不要把 ClickOnce 单纯看作”一种 installer 类型”。
实际上,ClickOnce 是一种统一负责以下事务的 发布模型。
- 要发布哪个版本
- 该版本包含哪些文件
- 如何检测更新
- 从哪里获取更新
- 如何在每个用户专属的安全位置保存
- 启动时如何确认完整性
ClickOnce 的主体并不是 setup.exe 本身,把它看作 以清单为核心,统一处理发布、更新和缓存管理的机制,会更贴近其本质。
在当前的 .NET 中,ClickOnce 本身依然是一个普通的候选方案。Visual Studio 针对 .NET Core 3.1 及 .NET 5 以后的版本使用 Publish 工具,如果需要手动处理清单,则要使用 dotnet-mage.exe。
ClickOnce 所负责的职责
flowchart LR
CO["ClickOnce"]
V["发布哪个版本"]
U["从哪里获取更新"]
S["保存在每个用户专属的安全位置"]
I["确认完整性后启动"]
CO --> V
CO --> U
CO --> S
CO --> I
3. 构成 ClickOnce 的要素
要理解 ClickOnce 的机制,抓住以下 4 点是最快的途径。
| 要素 | 作用 |
|---|---|
部署清单 (.application) |
表示当前应发布的版本、更新位置、更新方式等 |
应用程序清单 (*.exe.manifest) |
表示该版本的应用本体、依赖文件、哈希、入口点等 |
| 应用程序文件 | exe、dll、config、数据文件等 |
setup.exe(可选) |
用于确认并安装前提条件的 bootstrapper,在需要特定运行时或依赖组件时使用 |
这里的核心是 两种清单。
- 部署清单 表示”这个应用目前正确的版本是哪一个”
- 应用程序清单 表示”该版本的具体内容是什么”
也就是说,ClickOnce 的更新判定首先从部署清单开始,而实际要下载什么内容,则由应用程序清单决定。
4 个要素之间的关系
flowchart LR
Setup["setup.exe<br/>可选<br/>确认 / 安装前提条件"]
Deploy["部署清单 (.application)<br/>发布哪个版本<br/>更新位置 / 更新条件"]
App["应用程序清单 (*.exe.manifest)<br/>该版本的内容<br/>文件列表 / 哈希 / 入口点"]
Files["应用本体<br/>exe / dll / config / data"]
Cache["ClickOnce 缓存<br/>per-user / per-application"]
Setup --> Deploy
Deploy --> App
App --> Files
Files --> Cache
setup.exe 并非主角,而是辅助角色
setup.exe 经常很显眼,但它并不是 ClickOnce 的主角,而是 负责确认并安装前提条件的辅助角色。
例如,当需要正确版本的 .NET 运行时或额外的可再发行组件时,setup.exe 会先把这些准备好,之后才进入 ClickOnce 本体的发布流程。
4. 从安装到启动的流程
把 ClickOnce 的流程按实务角度大胆简化,就是这样的。
- 用户打开 Web 页面或文件共享上的
setup.exe或.application - 如果使用
setup.exe的配置,会先确认前提条件并安装缺失部分 - ClickOnce 读取部署清单
- 读取部署清单所指向的应用程序清单
- 获取所需文件,并放置到每个用户专属的 ClickOnce 缓存中
- 如果配置为支持离线使用,会注册到开始菜单或应用列表中
- 之后从 ClickOnce 的管理之下启动应用
重点是:这并不是像普通 installer 那样把文件放进 Program Files 的思路。
ClickOnce 应用会进入 每个用户专属的安全缓存区域,并按应用和用户分别隔离。这是 ClickOnce 的一大特点。
从安装到首次启动
sequenceDiagram
participant U as 用户
participant P as setup.exe / .application
participant D as 部署清单
participant A as 应用程序清单
participant C as ClickOnce 缓存
participant X as 应用本体
U->>P: 打开
Note over U,P: 使用 setup.exe 的配置中<br/>会先进行前提条件确认
P->>D: 获取并读取
D->>A: 参照目标版本
A->>C: 获取所需文件并确认完整性
C->>X: 部署并启动
仅在线使用与支持离线使用
ClickOnce 大致有两种呈现方式。
- 仅在线使用:以发布位置为起点执行的形式,常驻安装的感觉较弱
- 支持离线使用:安装到用户终端,也可以从开始菜单启动的形式
在社内业务应用中,实务上大多会选择 支持离线使用。
flowchart LR
subgraph Online[仅在线使用]
O1["以发布位置为起点启动"]
O2["常驻安装的感觉较弱"]
O3["容易以网络为前提"]
O1 --> O2 --> O3
end
subgraph Offline[支持离线使用]
F1["安装到用户区域"]
F2["注册到开始菜单"]
F3["从本地启动"]
F4["在指定时机确认更新"]
F1 --> F2 --> F3 --> F4
end
5. 更新机制
ClickOnce 最容易理解的优势,还是在于 更新模型是内置(built-in)的。
更新判定从部署清单开始
ClickOnce 应用会读取部署清单,确认:
- 是否存在新版本
- 是否为必需更新
- 从哪里获取
在此基础上一旦开始更新,ClickOnce 会通过 file patching 来避免冗余的重复下载。从直观上理解,可以认为它是 将新版的应用程序清单与当前版本进行比对,只去获取发生变化的文件,这样在实务中会比较容易理解。
关于更新确认的思路,整理成以下 3 种模式会比较容易理解。
- 启动前确认
- 启动后确认
- 由应用自行提供”检查更新”的 UI
不过,.NET Framework 与 .NET 5+ 在可用的 API 与设置 UI 上存在差异。重要的是 不要仅凭对旧版 ClickOnce 文章的记忆就直接开始实现。
更新流程
flowchart TD
Start["应用启动"]
Check["确认部署清单"]
New{"是否存在新版本"}
Run["直接启动"]
Get["获取新版的应用程序清单"]
Compare["比较文件签名 / 哈希"]
Download["获取发生变化的部分"]
Switch["构建新版本并切换"]
Restart["必要时重启后以新版本运行"]
Start --> Check --> New
New -- 否 --> Run
New -- 是 --> Get --> Compare --> Download --> Switch --> Restart
此外,如果没有网络连接,则不会进行更新确认,而是直接运行现有版本,这个前提也提前掌握好,实务中会更不容易混乱。
版本会分开保存
ClickOnce 与”直接就地覆盖当前文件”的思路不同,更接近于 先把新版本完整构建好,再进行切换。
此外,ClickOnce 缓存会将 当前版本与前一个版本 分开保存。这是它不容易污染环境、也容易避免版本冲突的原因之一。
flowchart TB
subgraph UA[用户 A 的 ClickOnce 缓存]
APrev["前一版本"]
ACur["当前版本"]
AData["设置 / 数据"]
end
subgraph UB[用户 B 的 ClickOnce 缓存]
BPrev["前一版本"]
BCur["当前版本"]
BData["设置 / 数据"]
end
APrev --> ACur
AData --> ACur
BPrev --> BCur
BData --> BCur
这里的重点有两个。
- 不容易与其他用户混在一起
- 不容易与其他版本冲突
所谓的 DLL Hell 之所以容易避免,这种结构起了很大作用。
6. ClickOnce 的优势
ClickOnce 的好处并不只是”发布简单”。在实务中真正发挥作用的,大致是以下这些方面。
6.1 容易发布给标准用户
ClickOnce 与 per-user 前提的发布方式相性良好,最大的优点是 可以在不需要管理员权限的情况下轻松安装。
在社内业务应用中,常见的情况是:
- 使用者是标准用户
- 不想每次都向 IT 部门申请安装
- 但又不想停止更新
在这种条件下,ClickOnce 相当强大。”每个用户的区域中,安全地、连同更新一起安装进去”这个前提,从一开始就与 ClickOnce 契合。
6.2 不需要自行实现更新
如果从零开始构建自动更新,要做的事情会比看起来多得多。
- 新版本检测
- 下载
- 完整性确认
- 与旧版本的切换
- 失败时的恢复
- 更新 UI
- updater 本身的处理
这些工作中的相当一部分,ClickOnce 已经通过既有模型具备了。
flowchart LR
subgraph Custom[自制 updater 需要承担的职责]
C1["新版本检测"]
C2["下载"]
C3["完整性确认"]
C4["切换"]
C5["失败时恢复"]
C1 --> C2 --> C3 --> C4 --> C5
end
subgraph Click[可以交给 ClickOnce 的职责]
K1["新版本检测"]
K2["获取与验证"]
K3["切换"]
K1 --> K2 --> K3
end
当然,并不是什么都能自由定制。不过,社内应用所需要的”足够好的更新”,用它相当容易满足。
6.3 应用之间不容易冲突
ClickOnce 应用会 按应用、用户和版本分别隔离。
因此,以往常见的
- 共享组件的版本冲突
- 覆盖某个 DLL 导致其他应用损坏
- 手动替换导致环境被污染
这类事故会更不容易发生。
6.4 容易从 Visual Studio 发布
ClickOnce 与 Visual Studio 的发布功能相性良好,距离实际发布的路径很短,这也是一个优点。
在进入 MSI authoring 那样的另一层复杂度之前,就可以先
- 先发布
- 先分发
- 先让更新运转起来
- 先获得现场反馈
这样的流程很容易搭建起来。
6.5 设置迁移也相对直接
如果使用默认的应用程序设置提供程序,ClickOnce 在更新时具备 将前一版本的设置合并到新版本 的机制。
不过,这是 以默认设置提供程序为前提 的。如果涉及自定义设置保存、自定义提供程序,或更改了保存位置,那自然就不能照搬这个结论了。
7. 适用场景
ClickOnce 特别适用的,大致是以下这类项目。
| 情况 | 与 ClickOnce 相性良好的原因 |
|---|---|
| 社内使用的 WinForms / WPF 业务应用 | 标准用户发布与自动更新正好契合 |
| 只需按用户单位安装即可 | per-user 发布很自然 |
| 想通过网站或 UNC 共享发布 | 发布渠道简单 |
| 更新频率大约在每月到每周之间 | built-in 更新足以顺利运转 |
| 不想把更新 UI 作为产品价值来精心打造 | 可以直接使用现成的更新模型 |
举一些实务中相性良好的具体例子,大致是这些。
- 社内业务录入应用
- 报价、订单、库存等桌面业务工具
- 设备配置用的辅助应用
- 发布给营业所、工厂、后台部门的社内专用客户端
- 需要更新,但还不到要专门做一个 updater 的应用
在这类应用中,让发布与更新保持简单,本身就是一种价值。而 ClickOnce 正好能直接满足这种价值。
是否适用的判断树
flowchart TD
S["整理需求"]
Q1{"是否为 WinForms / WPF 等<br/>.NET 桌面应用"}
Q2{"per-user 发布是否足够"}
Q3{"是否想安装给标准用户"}
Q4{"能否通过 Web / 文件共享发布"}
Q5{"是否不需要过度打造更新 UX"}
G["ClickOnce 相当有力"]
O["比较其他方案"]
S --> Q1
Q1 -- 否 --> O
Q1 -- 是 --> Q2
Q2 -- 否 --> O
Q2 -- 是 --> Q3
Q3 -- 否 --> O
Q3 -- 是 --> Q4
Q4 -- 否 --> O
Q4 -- 是 --> Q5
Q5 -- 是 --> G
Q5 -- 否 --> O
8. 不适用场景
另一方面,不应该勉强使用 ClickOnce 的场景也很明确。
8.1 需要 machine-wide install
ClickOnce 基本上是 per-user 的。
- 想为所有用户统一安装
- 想以
Program Files为前提安装 - 想对整个终端进行安装与管理
如果是这样,用 MSI 之类的方案会比 ClickOnce 更自然。
8.2 Windows service / driver / shell extension / 深度 COM 注册
这些属于 深度触及 OS 的话题。
- Windows service
- driver
- in-process shell extension
- 以机械式 COM 注册为前提的构成
一旦涉及到这些,就脱离了 ClickOnce”轻量发布”的世界观。
8.3 需要 package identity
选择 MSIX 的理由之一,就是想获得 package identity 这一需求。
ClickOnce 并不是朝这个方向设计的。如果需要的是 modern packaging 或以 Windows 的 package identity 为前提的功能,应该优先考虑 MSIX。
8.4 想把更新 UX 与分发渠道当作产品来掌控
例如:
- stable / beta / preview 渠道
- 分阶段发布
- 根据 telemetry 调整 rollout 比例
- 对后台下载的精细控制
- 自定义的 rollback 策略
- updater 本身复杂的生命周期
一旦想要这些,ClickOnce 的内置更新就会显得不够用。
8.5 只需放置即可运行的工具
反过来,也存在更简单就足够的情况。
- 整个文件夹放上去就能运行
- 更新用手动替换也可以
- 用 U 盘传递
- 处于封闭网络,简单性是第一优先
这种情况下,xcopy 发布方式有时摩擦会更小。
哪些需求该转向其他方案
flowchart LR
A1["面向所有用户的安装"] --> B1["MSI / 部分 MSIX"]
A2["service / driver / shell extension / 深度 COM"] --> B2["MSI / 专用 installer"]
A3["需要 package identity"] --> B3["MSIX"]
A4["分阶段发布 / 渠道 / 自定义 UX"] --> B4["自制 updater"]
A5["只需放置即可"] --> B5["xcopy"]
ClickOnce 并不是无论哪个方向都万能,但它是一种 在复杂度恰到好处的项目中很强 的方式。
9. 实务中容易踩坑的地方
ClickOnce 很方便,但如果草率导入,会有些坑。以下几点最好提前掌握,会轻松很多。
9.1 不要用”普通 installer”的感觉去看待它
ClickOnce 并不是那种把文件放到固定安装位置、便于人工直接管理的模型。
其实体会进入 ClickOnce 所管理的缓存中,按版本分别隔离。因此,
- 以固定 EXE 路径为前提的运维方式
- 手动直接覆盖的运维方式
- 由人来掌控实体文件位置的运维方式
与这些方式相性都不好。
ClickOnce 是一种 不是由人来管理文件放置位置,而是通过清单来管理发布状态 的方式。
9.2 许多旧的 ClickOnce 文章都以 .NET Framework 为前提
这一点需要特别注意。
即便到现在,搜索结果靠前的位置仍然经常出现 .NET Framework 时代的 ClickOnce 文章。不过,在当前的 .NET 中,情况有些不同。
- 在 .NET Core 3.1 / .NET 5 / .NET 6 中无法直接使用
ApplicationDeploymentAPI - 在 .NET 7 及以后版本中,部分部署属性可以通过环境变量读取
- 如果要手动处理清单,前提是要用
dotnet-mage.exe - Visual Studio 方面,以往基于旧版 Publish Wizard 的说法有时也不能照搬使用
即使自认为”对 ClickOnce 很熟悉”,也不要 凭着旧的记忆直接去实现,这样更安全。
9.3 前提条件要单独考虑
ClickOnce 本身是一种发布模型,但应用要运行起来,有时还需要满足一些前提条件。
- 所需的运行时
- 额外的可再发行组件
- 其他依赖项
这时使用 setup.exe 的 bootstrapper 构成会很有效。反过来,如果这里处理得含糊不清,就会出现”用 ClickOnce 成功发布了,但却运行不起来”的情况。
9.4 设置能否迁移取决于”保存了什么、如何保存”
如果使用默认的设置提供程序,更新时的设置迁移会比较直接。不过,
- 自定义设置提供程序
- 以 roaming 为前提
- 自行更改了设置保存位置
- 不同版本之间大幅改变了设置结构
如果是这些情况,自然就不能简单照搬了。
9.5 不要轻视签名与更新路径
ClickOnce 具备发布与更新机制,但这并不意味着安全责任就此消失。
尤其是在生产环境中,
- 如何管理签名证书
- 如何显示发行者名称
- 如何管理更新源
- 如何区分测试用的自签名与正式签名
最好在一开始就整理清楚。
flowchart TD
Cert["代码签名证书"]
AppMan["应用程序清单"]
DepMan["部署清单"]
Verify["客户端进行验证"]
Run["更新 / 运行"]
Tamper["清单被篡改"]
Stop["验证失败并停止"]
Cert --> AppMan
Cert --> DepMan
AppMan --> Verify
DepMan --> Verify
Verify --> Run
Tamper -. 验证失败 .-> Stop
“有自动更新 = 安心”这个等式并不成立,信任什么、以及如何维持这种信任,需要单独考虑。
9.6 如果要迁移部署位置,请重新检查 deploymentProvider
这一点不起眼,但在实务中相当容易踩坑。
已安装的 ClickOnce 应用,会把部署清单中 deploymentProvider 所指向的位置当作更新源去查看。也就是说,即使把整个发布文件夹复制到另一个 URL 或另一个共享位置,如果不更新 deploymentProvider,客户端仍可能持续查看原来的位置。
而且,一旦手动更改了清单,就需要 重新签名。
从发布到更新生效的运维流程
flowchart TD
Build["构建"]
AppManifest["生成新的应用程序清单"]
SignApp["对应用程序清单签名"]
UpdateDep["将部署清单更新为新版本"]
SignDep["对部署清单签名"]
Publish["部署到发布位置"]
Client["客户端检测到更新"]
Build --> AppManifest --> SignApp --> UpdateDep --> SignDep --> Publish --> Client
归根结底,在 ClickOnce 的运维中重要的,与其说是 有没有把文件放上去,不如说是 清单与签名之间的一致性是否得到保证。
10. 总结
如果用一句话概括,ClickOnce 就是
一种可以将 .NET 的 Windows 桌面应用 以 per-user 方式轻松发布,并以低成本连更新一起运转的机制
它的优势主要体现在以下几点。
- 容易发布给标准用户
- 具备内置的更新模型
- 容易只更新发生变化的部分
- 容易将应用与版本分离
- 容易从 Visual Studio 发布
- 与社内业务应用相性良好
不过,它并非万能。
- machine-wide install
- service / driver / shell extension
- 深度 COM 注册
- package identity
- 自定义渠道或分阶段发布
- 将更新 UX 作为产品价值精心打造
如果存在这些需求,就应该从 MSI / MSIX / 自制 updater 的方向考虑,而不是 ClickOnce。
ClickOnce 并不是 什么都能装下的简易 installer,但在 适合的项目中,它至今仍相当强大。
如果想发布的是
- .NET 的 Windows 业务应用
- 按用户单位安装即可满足需求
- 想发布给标准用户
- 不想自行维护更新机制
那么 ClickOnce 就是一个相当有力的候选方案。
11. 相关文章
- 如何选择 Windows 应用的发布方式 - MSI / MSIX / ClickOnce / xcopy / 自制 updater 的判断表
- 自动更新程序是信任边界 - 为何仅靠 HTTPS 还不够
- Windows 的管理员特权何时才是必需的 - UAC、受保护区域与设计上的判断方法
相关主题
与本主题相关的主题页面。可以以本文为起点,进一步访问相关服务或其他文章。
Windows 技术主题
汇总 Windows 开发、故障排查、既有资产利用等技术主题的入口页面。
与本主题相关的服务
本文与以下服务页面相关联,请从相近的入口进入查看。
Windows 应用开发
在社内业务应用、设备配置工具、既有软件改造等项目中,ClickOnce / MSI / MSIX / xcopy 哪种方式摩擦最小,会因实现前的梳理工作而有很大差异。
技术咨询与设计评审
“ClickOnce 是否足够”“是否应该转向 MSIX 或 MSI”“自动更新应该用 built-in 解决,还是自行维护”,这类判断如果在实现前先整理清楚,会更容易做出决定。
作者简介
小村 豪
小村软件有限公司 代表
主要从事 Windows 软件开发、技术咨询与故障排查,尤其擅长处理保留既有资产的项目,以及原因难以查明的故障调查。
12. 参考资料
- Microsoft Learn - ClickOnce deployment and security
- Microsoft Learn - ClickOnce for .NET on Windows
- Microsoft Learn - How ClickOnce performs application updates
- Microsoft Learn - Choosing a ClickOnce update strategy
- Microsoft Learn - ClickOnce deployment manifest
- Microsoft Learn - ClickOnce application manifest
- Microsoft Learn - ClickOnce cache overview
- Microsoft Learn - ClickOnce and application settings
- Microsoft Learn - Install prerequisites with a ClickOnce application
- Microsoft Learn - ClickOnce and Authenticode
- Microsoft Learn - Security, versioning, and manifest issues in ClickOnce deployments
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
委托开发 Windows 应用程序前该梳理的事项
在委托外包开发 Windows 应用程序之前,梳理现有软件改造、设备联动、COM/ActiveX、发布与更新、维护等需要注意的要点。
Windows出现“Windows 已保护你的电脑”提示的原因
整理Windows应用分发时出现SmartScreen警告的原因,从代码签名、EV/OV证书、Azure Artifact Signing、MSIX、Microsoft Store、ClickOnce、企业内部分发到App Control,以实务角度梳理应对方法。
Windows 应用发布方式怎么选 - MSI / MSIX / ClickOnce / xcopy / 自定义 updater 判断指南
Windows 应用的发布方式不是 installer 形式的偏好问题,而是与 OS 的耦合程度和更新责任由谁承担的选择。本文从实务角度整理 MSI / MSIX / ClickOnce / xcopy / 自定义 updater 的选型思路。
用 PerfView 与 dotnet-trace 定位“变慢”的原因 ── .NET 性能排查实务入门
当业务应用出现“变慢”“CPU 占满”“偶尔卡死”时,该用哪个工具看什么?本文梳理 PerfView 与 dotnet-trace 的分工、CPU 采样的解读方法(inclusive/exclusive)、用 ThreadTime 排查阻塞时间,以及与 EventSourc...
Windows 事件日志・ETW 入门 ── 让业务应用程序的日志接入操作系统标准机制
Windows 业务应用程序的日志,是不是只靠文件日志来解决?事件日志与 ETW,是运维人员和操作系统标准工具所能看到的另一层记录。本文整理三种手段的分工方式、.NET 中的写入方法、通过 EventSource 进行的 ETW 埋点、收集与排查的实务做法,以及来源未注册、...
常见问题
汇总了咨询这一主题时常见的问题。
- ClickOnce 是什么?
- 这是一种用于按用户单位轻松发布 .NET Windows 桌面应用,并包含自动更新在内的发布技术。官方说明中将其定义为:一种可通过最少的用户操作完成安装与运行,并具备自我更新能力的 Windows 应用发布技术。实际上,它是以清单(manifest)为核心,统一处理发布、更新与缓存管理的发布模型;应用会保存在每个用户专属的安全缓存区域中,并按应用、用户和版本分别隔离保存。
- ClickOnce 今后还能用吗?它不是过时的技术吗?
- 在当前的 .NET 中,ClickOnce 依然是一个普通的候选方案。Visual Studio 针对 .NET Core 3.1 及 .NET 5 以后的版本使用 Publish 工具,如果需要手动处理清单,则要使用 dotnet-mage.exe。不过需要注意的是,情况与 .NET Framework 时代有所不同:在 .NET Core 3.1 / .NET 5 / .NET 6 中无法直接使用 ApplicationDeployment API,而在 .NET 7 及以后版本中,部分部署属性需要通过环境变量读取。不要仅凭对旧文章的记忆就直接开始实现,这样比较安全。
- ClickOnce 适合哪些应用?
- 特别适合社内使用的 WinForms / WPF 业务应用:想在不需要管理员权限的情况下发布给标准用户、per-user 发布已经足够,并且希望具备内置(built-in)更新能力的场景。发布渠道通过网站或文件共享即可满足。反过来,如果需要面向所有用户的 machine-wide 安装、Windows service、driver、shell extension、深度 COM 注册,或者需要 package identity,又或者想要掌控更新渠道与分阶段发布,就不适合用 ClickOnce,应该从 MSI / MSIX / 自制 updater 的方向来考虑。
- ClickOnce 的自动更新机制是怎样的?
- 更新判定从部署清单(.application)开始。应用会读取部署清单,确认是否存在新版本、是否为必需更新,以及从哪里获取更新。更新时会通过 file patching 机制,将新版的应用程序清单与当前版本进行比对,只获取发生变化的文件,从而避免冗余的重复下载。ClickOnce 缓存会将当前版本与前一个版本分开保存,其思路是先完整构建好新版本,再进行切换。如果没有网络连接,则不会进行更新确认,而是直接运行现有版本。
作者简介
本文作者的个人简介页面。
Go Komura
小村软件有限公司 代表
以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。