.net程序如何自行更新?

mrh*_*967 17 .net

我写了一个程序,如果它在服务器上找到一个更新的版本,它会更新自己,但我发现它很难干净地实现.

检查远程服务器并下载文件很简单但是那又如何呢?它不能简单地File.Copy("newversion.exe","myprogram.exe"),因为myprogram正在运行且文件被锁定.

我通过下载两个文件newversion和更新来做到这一点.myprogram然后启动更新并退出.更新等待两秒钟,复制,然后启动myprogram(现在是更新版本)并退出.myprogram在启动时查找更新并删除它,如果找到则返回newversion.mypogram现在是新版本,没有留下任何文件.

必须有比这更好的方法,那么程序更新自己的.net方式是什么?

PS.对不起,如果这个问题出现两次 - 我第一次提交时遇到'堆栈溢出已损坏'页面.

Phi*_*ace 15

查看ClickOnce Deployment是否为您提供所需的服务.


Che*_*eso 7

我看着Wix和ClickOnce,并不喜欢它们.对于单文件"xcopy部署"类型的WPF应用程序,我想要更简单的东西.

所以我建了一个.这是一个AppUpdater类,您可以将其放入任何WPF应用程序中,并在必要时自动更新.

检查版本号并下载最新版本很容易.

下一部分不太容易.你如何替换正在运行的应用程序?我采取的方法是这样的:

  • 每次运行时,应用程序都会检查一个众所周知的URL版本.如果版本不晚于当前正在执行的应用程序的版本,则没有其他任何事情要做.

  • 如果以后版本为IS,那么app会抓取一个名为Mutex,将自身(Assembly.GetExecutingAssembly().Location)复制到临时位置,然后从该临时位置启动一个新进程(进程#2),并传递一个命令行说"你正在尝试更新"并给出原始exe位置的参数.

  • 进程#1关闭自己.

  • 进程#2启动 - 它看到它正在尝试更新,因此它会下载更新的映像,并将其放在原始位置(在命令行上传递的位置).它不是等待2秒或任何任意时间,而是使用命名的互斥锁来确定进程#1何时退出.

  • 过程#2然后使用原始位置启动过程#3.

  • 进程#2关闭,释放其命名的Mutex.

  • 进程#3启动.它会检查版本URL - 看到它是最新的.无需更新.进程#3还等待进程#2释放其Mutex,然后删除EXE的临时副本 - 进程#2使用的临时副本.


编辑

在回应评论时,是的,听起来很复杂.但是AppUpdater模块中所有这一切的逻辑.要从WPF应用程序中使用它非常简单:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        // add this line in your constructor
        if (UpdaterCheck())  this.Hide();
    }

    // this is all boilerplate
    private Ionic.AppUpdater.Wpf.Updater _updater;
    private string _manifestUrl = "http://example.org/AppUpdates/MyApplication/Manifest.xml";
    private string _infoUrl     = "http://example.org/MyApplication.html";
    private string _description = "MyApplication is a delightful application; it does x, y, and z. ";
    // Obtain the publicKey XML from the ManifestTool that ships with Ionic AppUpdater.
    // The following string is Ionic's public key.  You will need a different one.
    // Consult the Readme for more information.
    private string _publicKeyXml = "<RSAKeyValue><Modulus>sZqhvF0KX6m4blah..blah...=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

    // add this boilerplate method
    private bool UpdaterCheck()
    {
        _updater = new Ionic.AppUpdater.Wpf.Updater("This is MyApplication.",
                                                    _infoUrl,
                                                    _description,
                                                    _manifestUrl,
                                                    _publicKeyXml);
        return _updater.Status.IsUpdating;
     }
    ...
Run Code Online (Sandbox Code Playgroud)

您可以在这里运行的详细信息和代码.

它仅适用于WPF应用程序,但构建WinForms版本的东西非常简单.同样的想法,虽然生成UI的一些逻辑必须改变.

  • 我认为,当你到达响应结束时,比clickonce"更简单"不再有效( - : (2认同)