更新必须由独立进程(如updater.exe)完成,主程序外置启动后退出;更新器需管理员权限、校验哈希、原子替换、回退备份,并用服务端语义版本+构建号比对,httpclient重试下载,进度回调用iprogress。

更新逻辑必须由主程序外置启动
不能在当前进程内直接覆盖自身文件,Windows 会锁定正在运行的 .exe 和引用的 .dll。正确做法是启动一个独立的更新器进程(如 Updater.exe),由它负责下载、校验、替换,再重新拉起主程序。
- 主程序检查更新后,用
Process.Start("Updater.exe", "--app-path " + Application.ExecutablePath)启动更新器,并立即Application.Exit() - 更新器需以管理员权限运行(尤其要写入
Program Files),可通过清单文件声明requireAdministrator或在启动时检测并提权 - 更新器退出码建议区分:0=更新成功并已重启主程序,1=无更新,2=下载失败,3=校验失败——主程序可据此决定是否弹提示
版本比对不能只看文件时间或简单字符串
用户可能手动复制旧版文件,或服务器部署时未更新版本号。必须用服务端返回的权威版本标识,推荐组合使用:
新版本程序更新主要体现在:完美整合BBS论坛程序,用户只须注册一个帐号,即可全站通用!采用目前流行的Flash滚动切换广告 变换形式多样,受人喜爱!在原有提供的5种在线支付基础上增加北京云网支付!对留言本重新进行编排,加入留言验证码,后台有留言审核开关对购物系统的前台进行了一处安全更新。在原有文字友情链接基础上,增加LOGO友情链接功能强大的6种在线支付方式可选,自由切换。对新闻列表进行了调整,
-
semantic version(如2.1.3)做逻辑比较,用SemanticVersion类或正则解析后逐段比对 - 附加一个单调递增的
build number(如21304),避免语义版本相同但实际二进制不同 - 绝对不要依赖
AssemblyVersion属性自动递增——它常被 CI 覆盖或人为冻结
下载和替换过程必须带校验与原子性
直接覆盖 DLL 或 EXE 文件极易导致程序损坏。关键操作必须有回退能力:
- 下载新包时,先保存为临时名(如
MyApp.new.zip),下载完成后用SHA256校验哈希值,匹配不上就删临时文件并报错 - 解压时指定独立临时目录(如
%TEMP%\MyAppUpdate\),全部解压完成再执行替换 - 替换文件用
File.Replace方法(支持备份原文件),例如:File.Replace(newPath, originalPath, backupPath);
,而非File.Delete + File.Move - 若更新涉及配置文件,不要覆盖用户修改过的
appsettings.json,应合并或提示手动处理
HTTP 客户端要处理常见网络异常场景
内网环境、代理、证书错误、断点续传缺失都会让更新失败。不要用裸 WebClient:
- 改用
HttpClient,设置合理的Timeout(至少 90 秒)和MaxResponseContentBufferSize - 添加重试逻辑(如 3 次,指数退避),对
HttpRequestException、TaskCanceledException分类重试,但跳过 4xx 错误 - 如果服务端支持,请求头加
If-None-Match(ETag)或If-Modified-Since避免重复下载 - 进度回调必须用
IProgress<t></t>而非 UI 控件直接赋值,防止跨线程异常









