实现自更新软件的最佳方法

13
我们有一个最小化的“更新程序”exe,它检查远程URL是否有更新,下载并替换磁盘上的文件,然后启动真正的应用程序。但是,如果我们想要替换更新程序EXE,则我所知道的有两个选项:
  1. 影子复制程序集,.Net将创建EXE(和任何引用的程序集)的影子副本,并加载这些程序集,以便可以替换非影子程序集,并在下次启动应用程序时使用。

  2. 识别被替换的文件并在磁盘上重命名/移动它们。Windows似乎允许重命名/移动锁定的文件,因此我们可以移动文件并复制新的程序集。同样,在下次启动应用程序时,我们将启动新的程序集。这种方法在这里提到。

这第二种方法是推荐的方法吗?这种方法有什么缺陷吗?
6个回答

12

另一种选择是:当主应用程序想要更新自身时,它会生成一个新的更新程序进程,然后关闭自身。在此期间,生成的进程等待主应用程序关闭(即进程消失),然后更新所有必要的文件(包括 .exe 文件)。之后,它只需重新启动主应用程序并退出更新程序进程。


@jpierson,它很好用:)。我已经使用这种方法来开发自己的应用程序两年了。 - Igor Brejc
不确定这里的“生成”是什么意思。生成的进程肯定还是引用同一个 .exe 文件和其他库文件,因此无法被覆盖,对吧? - jnt
@jnt 不,我的情况是生成的进程是从一个独立的 .exe 运行的,它不引用主 .exe 或任何库文件。 - Igor Brejc

9
我使用第二种方法没有任何问题。只需确保正确下载了所需的程序集。;)
运行Update.exe并让它执行以下操作:
1.将新的update.exe下载为update.ex_
2.将update.exe重命名为update.bak(您可以重命名它,但不能覆盖它)
3.将update.ex_重命名为update.exe 4.重新启动update.exe 我已经成功地完成了这些步骤,并在400个客户的实时环境中运行测试,没有遇到任何问题。

如何重新启动当前正在运行的程序?有简单的方法吗? - chillitom
@chilitom:process.start(Application.StartupPath&"\ myprogram.exe"):end - Stefan

5

这可能是最好的选择,因为它应该有助于标准化在Windows Vista和未来版本的Windows中所需的安全级别升级/降级。 - Grant Peters
我们目前没有使用ClickOnce,因为使用我描述的文件复制方法更容易,而且我们还有一个定制的更新过程,用于安装应用程序旁边的SQL数据库。然而,ClickOnce是官方的Microsoft解决方案,我们将会更深入地研究它,以便未来使用,因此我选择这个作为被接受的答案。谢谢。 - redcalx
3
ClickOnce 是一场噩梦,因为它不灵活、过于复杂、似乎没有得到强有力的微软支持,并且非常特定于每个用户的部署情况。 - jpierson

3
在我工作的一个项目中,有两个可执行文件。我们称它们为A和B。
A存在的唯一原因是启动B。 因此,当B(真正的应用程序)下载更新时,如果需要,它可以替换A。
如果应用程序通过A重新启动,A会在启动B之前检查是否下载了某些文件并替换它们。

最近我发现一个正在运行的可执行文件无法被覆盖,但可以被重命名。我已经在测试应用程序中尝试过这个技巧,并将使用它来开发自己的应用程序自更新组件。 - jpierson
1
请查看影子复制(http://msdn.microsoft.com/en-us/library/ms404279.aspx)。我们使用它来允许终端服务器上的客户端在其他用户同时运行应用程序的情况下更新客户端软件。 - sloth

0
我们使用自家应用程序的方式: 应用程序快捷方式指向更新器。 1. 显示停机通知/截止日期消息。 2. 更新程序执行更新检查。 3. 下载并安装更新。 4. 启动应用程序。 5. 应用程序执行更新更新程序(在/update文件夹中检查Updater.fp7.gz)。 编辑:糟糕-错过了第五步。

2
你确实读了这个问题吗?在你的情况下,如何更新更新程序本身? - Lasse V. Karlsen

0

我基本上同意Stefan's Answer的观点,但如果您想在Windows Vista或Windows 7上正确处理UAC,并且您的应用程序已经正确安装在Program Files文件夹下或需要安装其他需要提升权限的依赖项,则可能无法正常工作。

在这种情况下,您可以执行基于msi的安装/补丁或安装运行所需安全性以覆盖Program Files文件夹中的文件的Windows服务。

如果您的应用程序是交互式的,则另一种选择是像Igor Brejc建议的那样生成一个新进程来进行更新,从而使您的应用程序有机会在更新期间提示提升权限。无论是交互式还是非交互式场景,使用上述补丁或Windows服务选项都将提供更好的用户体验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接