在决定使用ClickOnce发布你的软件前,应该知道的一些事情

目前我的工作是用C#开发一个桌面软件,安装到分布各地的数以百计的PC上,而且软件的修改和升级在未来很长一段时间内都很频繁,所以采用了微软的ClickOnce部署技术。这是一种上手很快使用方便的技术,但是你在决定把它应用在一个真正的商业项目中之前,应该了解一些将来可能会困扰你的问题,然后再判断一下是不是应该采用它。也许自己从头写一个自动升级框架反而更适合你的情况。

1,无法有效避免非法的下载

使用ClickOnce部署,你的软件的更新版可以发布到Web服务器上,当用户从开始菜单启动软件时,ClickOnce自动到指定的URL去检测是否存在新版本,并且从这个地址下载最新版本。问题在于,访问这个URL的过程是ClickOnce的内部机能,不和用户产生任何交互,也就没法进行有效的用户验证,要想ClickOnce正常更新,就必须保证这个URL能够任意访问。导致任何人只要在浏览器输入这个URL,就可以下载程序。

我没有找到好的解决方法,只能尽量加强软件本身的验证机制,即使有人非法下载安装了你的程序,让他无法使用也就罢了。

2,.NET Framework安装的烦恼

使用ClickOnce可以自动验证客户端PC是否安装了必需的.NET Framework以及其版本,并且可以自动启动一个下载程序从微软网站取得最新的安装文件。这是一个很有用的功能,一般情况下很难说服用户先去微软网站自己安装.NET Framework,大多数用户甚至根本不想知道什么是Framework(很难和他们解释清楚,为什么安装一个很小的软件,需要先安装一个几百兆大的叫做Framework的鬼东西)。然而在实际测试中发现了一个问题,用户的PC在公司内部通过代理才能访问互联网,不知什么原因,自动下载程序访问微软网站的速度慢到无法接受的程度,大约200M的Framework,60个文件,自动安装整整花费了一个多小时,远远不如自己直接下载安装包手动安装来的快。

幸好ClickOnce提供了一个选项,你可以把Framework和程序同时发布到自己的服务器上---但是,由于Visual Studio 2008的一个小Bug,这个选项是不好用的,你需要首先参考【Visual Studio 2008 Service Pack 1 (SP1) Realease Note】这个文档的2.3.1.1章节,手动修复这个小问题---现在你可以把Framework也发布到同一台服务器上进行下载了,只要你对自己服务器的速度有信心。

目前ClickOnce的下载机能不是很智能,不能断点续传:我这边碰到的一个情况就是由于服务器端的某代理软件的吞吐量不够,下载过程中失败的几率很高;另外如果是分布在多个地域的用户,不一定从哪里下载比较快,可能有的人反而访问微软官方网站比较快,但是ClickOnce并没有办法动态切换Framework下载地址。问题的关键是这个Framework自动下载安装的过程,没法灵活干预,只有在最理想的网络环境中才能真正发挥其优点。

3,.NET Framework安装的另一个烦恼

解决了上面的问题,我已经把软件和.NET Framework都部署在Web服务器上,鼠标一点,似乎一切都顺利。然而随着安装软件的用户数越来越多,自动安装过程中发生莫名错误

的投诉电话也越来越多。问题的原因在于,有些PC里面已经安装过不同版本Framework3.5SP1,但是又和我发布的版本不尽相同,比如没有语言包等等,ClickOnce没有办法自动覆盖安装。

Framework安装版本冲突的问题其实很常见,一般性的解决办法就是从控制面板删除现有的版本之后重启计算机,再重新安装即可。仍然不行的话可以借助微软官方提供的.NET Framework Cleanup工具彻底删除既存版本。但是这种解决方式对于最终用户来说不可接受,他们需要的是真正的ClickOnce:点击一下,帮我解决所有问题。

早知今日后悔当初,不该给用户一个过高的期望值,从一开始就教育他们老老实实的手动安装Framework就好了。

4,安装目录和卸载

软件投入使用后,用户投诉说,每次版本升级,都会经过很长时间的停顿才能看到程序的启动画面。调查之后发现:ClickOnce部署的程序会安装在C:\Documents and Settings\用户名\Local Settings\Apps\2.0文件夹下的一个随机生成的目录中。版本升级的时候,并不会直接把老版本删除,而是会随机生成另外一个目录,并且将现有的用户数据文件原封不动的复制过去。如果需要,可以在【控制面板-添加安装程序】中恢复到老的版本继续使用。程序卸载的时候,这个目录会自动被清空。

问题在于,我的这个软件启动后生成保存了数百个XML格式的模板文件和数据文件,大量小文件的磁盘复制操作非常耗时。开发和测试用的PC性能较好停顿还不太明显,不凑巧用户使用的是比较旧的笔记本电脑,结果版本升级过程变得非常明显地缓慢。

为了解决这个问题,可以把数据文件存放在一个独立的文件夹中,可是在卸载的时候,由于这些数据文件不属于ClickOnce的安装目录,也就不能自动删除。如果ClickOnce部署的程序在卸载的时候,能够调用一些自定义的处理就好了。

5,又有新问题了

有一天有个用户搬着他的笔记本电脑来到一个穷乡僻壤,这里没有宽带,只能用一个56K的小猫上网。当他打开软件想工作的时候,ClickOnce提醒他,软件有了更新的版本,你是要安装呢还是暂时跳过?由于对56K小猫的下载速度不太有信心,他选择了跳过:反正软件的旧版本也可以继续使用,还是先完成工作要紧。过了几天,这个用户回到了宽带社会,心想现在可以升级版本了,可是当他再次打开软件,却没有任何关于新版本的提示信息。

尽管我不太理解,ClickOnce就是这样工作的:如果你选择了【跳过】某个版本,那么你就永远【跳过】这个版本了,除非有比之更新的版本发布了,ClickOnce才会再次提醒你升级。如果是我的话,我会给用户提供【暂时跳过】和【不要再提醒我这个版本的更新】两个选择,可惜微软的技术人员似乎没有我这样善解人意。

这个问题的解决办法就是用代码的方式调用ClickOnce的API,强制其再次进行版本更新。可以参考MSDN的文章:【如何:使用 ClickOnce 部署 API 以编程方式检查应用程序更新】,但这种方式不太友好,更新过程中缺少一个可视化的进度显示,所以你可以参考MSDN的另一篇技术文章【执行异步更新】。

尽管MSDN提供了完美的编程示例,但是真实世界往往和示例有很大差距,我准备在另一篇文章里面专门探讨一下以API方式进行ClickOnce更新的时候会碰到的各种问题。

6,关于证书的两个问题

第一,发布时候用的测试用证书有个有效期问题,一年之后会导致无法继续更新。所以我发布之前干脆把证书取消掉了,似乎也没有问题,用户安装软件的时候会有个警告。第二,如果ClickOnce从https的地址更新,一定得保证服务器证书的有效性。如果从浏览器访问这个网址会弹出证书有效性的警告,ClickOnce的更新会失败。前几天碰到一台客户端PC,没有安装Windows的根证书(IT部门的人装系统的时候自作聪明把他认为不必要的组件都给省略了),无法验证服务器端证书的有效性,导致ClickOnce的更新不能进行。

7,设置选项虽然多,但对应实际需求的灵活性不足

ClickOnce的高级设置选项很多。所以当初选择用ClickOnce部署的时候没考虑到其实这些选项的灵活性不大,很难应付实际需求,特别是碰到对操作性 爱钻牛角尖的用户。
用户最后提出来的具体要求实际上是:
1,启动前进行更新;
2,网速过慢,更新过程过于耗费时间的时候,在途中可以随时取消掉,使用老版本启动;
3,用户工作完毕,软件关闭的时候,把刚才取消掉的更新重新执行一次。因为这时候不着急工作了,可以慢慢下载

单纯使用ClickOnce的选项设置根本无法实现这样的需求,而全部抛弃ClickOnce也为时已晚,最后只好取消掉选项设置里的自动更新,完全采用编码方式调用API的方式进行更新。过程中虽然遇到各种各样的小问题,好在最后基本实现了用户的要求。

不过这也是微软产品的特性:使用方便,看似强大...不灵活


本文所描述的问题,都基于VisualStudio2008 SP1,.NET Framework3.5 SP1的开发环境。

也许在最新版本的VisualStudio2010中,有些问题可能已经得到改善,我还没有研究过,另外有些问题可能只是我的误解,欢迎大家指正!


关于ClickOnce技术的简单介绍,可以参照互动百科:
http://www.hudong.com/wiki/CLICKONCE

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 仅以方便自己查阅记录前言1.静态库和动态库有什么异同?静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗...
    190CM阅读 4,178评论 0 4
  • 西江月(版本一) 日日深杯酒满,朝朝小圃花开。自歌自舞自开怀,无拘无束无碍。 青史几番春梦,黄泉多少奇才。不须计较...
    海边的蓝兔子阅读 842评论 0 0
  • N讀經: Deuteronomy7:7 The LORD did not set his affection on...
    NCNeverland阅读 148评论 0 0
  • 前段时间进行了QTP工具的自动化学习,在这之前陆陆续续地进行了python下接口自动化的基础学习,可是一直...
    sinfierno阅读 414评论 1 2