热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用ClickOnce发布你的软件前,应该知道的一些事情(一些常见问题解决方法)

目前我的工作是用C#开发一个桌面软件,安装到分布各地的数以百计的PC上,而且软件的修改和升级在未来很长一段时间内都很频繁,所以采用了微软的

目前我的工作是用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

--------------------------------------------------------------------------------------

 

posted on 2010-12-09 15:44 cs_liwei 阅读(638) 评论(7) 编辑 收藏

Feedback

#1楼 2010-12-09 16:59 阿水      

我使用ClickOnce还碰到过换个机器发布就有问题,客户端更新不了。使用相同的证书也不行,没办法。只能自己做了一个自动更新的东东  回复 引用 查看   

#2楼[楼主] 2010-12-09 17:22 cs_liwei      

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

#3楼 2010-12-09 17:49 G yc {Son of VB.NET}      

ClickOnce
在很大型的程序中,确实不适用

有些地方也不是很好用。。

至于更新那个,我想说一点
更新可以在高级选项设置是在启动前,还是启动后进行
平且执行频率等

另外,也可以指定运行的最低版本
  回复 引用 查看   

#4楼 2010-12-09 19:13 toEverybody      

不成熟的ClickONce
 回复 引用 查看   

#5楼[楼主] 2010-12-10 10:39 cs_liwei      

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

单纯使用ClickOnce的选项设置根本无法实现这样的需求,而全部抛弃ClickOnce也为时已晚,最后只好取消掉选项设置里的自动更新,完全采用编码方式调用API的方式进行更新。

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

#6楼[楼主] 2010-12-10 10:48 cs_liwei      

@toEverybody
呵呵,最后发现在ClickOnce上花费的时间,足够自己写一个单独的更新框架了...

考虑到如果当初技术选型的时候能看到这么一个文章我就不至于走这么多弯路,所以就总结了一下自己的经验教训
 回复 引用 查看   

#7楼 2010-12-10 13:19 G yc {Son of VB.NET}      

呵呵

ClickOnce 算是一个简单的轻量部署程序,或者说,通过 配置文件(*.Application)来安装东西(实际上就是复制。。。)

我隐约记得很久以前 MS演示过的东西。。

用没用 Application Block组件我就忘了

基本内容是, 将程序内容分组打包(在ClickOnce 高级选项里),也就是,除了程序运行必须的, 其他都可以不用下载(第一次安装),

然后程序启动后, 根据需求,进行自动下载并更新

我记得当时演示的程序是这样的

启动程序, 运行某个 功能, 然后 在后台更新版本号,
再次运行功能, 检测到更新, 并提示, 如果选择更新,就会后台下载,但现有功能可以继续运行。
当下载完成后,就会提示更新, 关闭现有组件,启动新的。


推荐阅读
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 在当前的软件开发领域,Lua 作为一种轻量级脚本语言,在 .NET 生态系统中的应用逐渐受到关注。本文探讨了 Lua 在 .NET 环境下的集成方法及其面临的挑战,包括性能优化、互操作性和生态支持等方面。尽管存在一定的技术障碍,但通过不断的学习和实践,开发者能够克服这些困难,拓展 Lua 在 .NET 中的应用场景。 ... [详细]
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 本文深入探讨了Ajax的工作机制及其在现代Web开发中的应用。Ajax作为一种异步通信技术,改变了传统的客户端与服务器直接交互的模式。通过引入Ajax,客户端与服务器之间的通信变得更加高效和灵活。文章详细分析了Ajax的核心原理,包括XMLHttpRequest对象的使用、数据传输格式(如JSON和XML)以及事件处理机制。此外,还介绍了Ajax在提升用户体验、实现动态页面更新等方面的具体应用,并讨论了其在当前Web开发中的重要性和未来发展趋势。 ... [详细]
  • 本文探讨了如何利用 jQuery 的 JSONP 技术实现跨域调用外部 Web 服务。通过详细解析 JSONP 的工作原理及其在 jQuery 中的应用,本文提供了实用的代码示例和最佳实践,帮助开发者解决跨域请求中的常见问题。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
  • 在更换电脑或重装系统时,用户经常需要处理诸如备份收藏夹、电子邮件、用户配置文件和常用文档等任务。尽管这些操作并不复杂,但却相当繁琐。本文介绍了一种利用Windows 7中的“轻松传送”功能,高效便捷地在两台电脑之间同步数据的方法,大大简化了这一过程。 ... [详细]
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • `chkconfig` 命令主要用于管理和查询系统服务在不同运行级别中的启动状态。该命令不仅能够更新服务的启动配置,还能检查特定服务的当前状态。通过 `chkconfig`,管理员可以轻松地控制服务在系统启动时的行为,确保关键服务正常运行,同时禁用不必要的服务以提高系统性能和安全性。本文将详细介绍 `chkconfig` 的各项参数及其使用方法,帮助读者更好地理解和应用这一强大的系统管理工具。 ... [详细]
  • 近期,针对Axis2默认凭据漏洞的攻击案例在安全社区引起了广泛关注。这些攻击通常利用Axis2的默认用户名和密码进行渗透测试,技术手段相对固定。本文在综合分析多个案例的基础上,详细探讨了该漏洞的安全风险,并提出了有效的防范措施,以帮助企业和开发者加强Web服务的安全防护。 ... [详细]
author-avatar
chingueen_306
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有