【问题标题】:Free solution for automatic updates with a .NET/C# app?使用 .NET/C# 应用程序自动更新的免费解决方案?
【发布时间】:2011-05-30 06:39:18
【问题描述】:

通过搜索,我可以看到这个问题已经被一次又一次地询问,但还不够充分,所以就这样吧。我是一个没有预算的爱好者开发者。我一直在开发的一个程序需要定期修复错误,我和用户已经厌倦了手动更新。

我,因为我目前的解决方案是通过FTP更新文本文件和我在网站上的下载链接,然后希望用户看到“有更新消息”,最后让他们费心手动下载坦率地说,更新太糟糕了。

用户,因为,嗯,“你会实施自动更新吗?” “会有自动更新功能吗?”如果我碰巧搞砸了更新过程,干草叉就会开始出现。

过去我调查过:

  • WinSparkle - 没有应用内更新,DLL 为 500 KB。我目前的解决方案是可执行文件中有几 KB,并且没有应用内更新。
  • .NET Application Update Component - 不幸的是我无法理解文档。
  • Eduardo Olivera's AutoUpdate - 除了处理未使用的文件之外,这似乎不支持任何其他功能。
  • wyUpdate - wyBuild 不是免费的,虽然 wyUpdate 规范可用,但它过于复杂和耗时。
  • AppLife Update - 同上最后一句。
  • ClickOnce - 在启动时实现启动的解决方法是巨大的、可怕的,对于这样一个简单的功能不值得。出版是一种痛苦;没有 FrontPage Extensions 的服务器需要手动 FTP 和替换所有文件

当你有像Sparkle 这样非常好的和简单的Mac OS X 实现时,Windows 上的情况是这样的,这非常令人失望。

【问题讨论】:

  • 创建您自己的自动更新程序会更简单 - 使用引导程序应用程序来启动您的应用程序。引导程序将检查更新是否可用,如果是,下载并安装它。如果安装需要管理员权限,那么您需要有 Windows 服务才能运行安装程序。
  • 我完全同情你;太糟糕了。你考虑过 ClickOnce 吗?我没有亲自使用它,但我听说它真的很好用。
  • @Maxim Zaslavsky - 是的,我已经考虑过了。我已经在我的原始帖子中列出了我的问题,所以你可能错过了。如果它是好的。
  • 哎呀,错过了最后一部分。对不起!祝你好运。

标签: c# .net auto-update


【解决方案1】:

自己实现!这会很有趣的。创建一个仅包含更新逻辑的单独应用程序,即在线获取文件,下载它们,替换本地文件,并以可视方式向用户显示。

因此,您的主应用程序可以检查更新,如果存在更新,它将提示用户进行更新。如果用户愿意,它会运行更新程序,关闭自身(这样更新就可以发生)并presto。

您需要的唯一东西是在 C#、FTP 访问和 IO 中现成可用的。

编辑:我知道这不是一件容易的事,但这是一个学习的绝佳机会:

  • 如何(正确)下载文件,以可扩展为 ftp、http 等的抽象方式。
  • 如何(正确地)对许多文件执行简单的任务 - 复制或覆盖它们(这意味着错误处理)。
  • 练习(因为没有“正确”的方法)对软件进行分层和封装。
  • 操作系统/其他软件(防病毒/防火墙/等)不配合如何处理。

这些都是我们都需要知道的事情 - 如果需要几周的时间来编写更新程序,这意味着您需要几周的学习时间。如果你不需要学习,是时候磨练你的技能了!如果你不知道你是否需要,是时候找出来了! :)

注意:我知道我确实需要学习更好的文件和网络 I/O

【讨论】:

  • +1...同意,添加一些安全性并检查以确保它只会复制到您签名的库中并不太复杂。
  • 但是,如果它在实现自制机制后简单、有趣且有点通用,那么为什么这些努力在很大程度上没有成功(即问题中提到的软件列表)?我认为当你进入它时可能会有更多细节,特别是考虑到你的更新需要交付到具有防火墙、安全性和 AV 软件等的不同平台。我可以预见很多边缘情况。
  • 我已经构建了这样一个库,听起来很简单,但很快发现它不是,特别是如果你想构建一些更强大的功能,比如拥有不同的源(磁盘、网络、网络)、不同的补丁机制(完整、增量等)、可恢复下载、在 xp、vista、win 7 等各种安全模型中工作。我并不是要劝阻你不要自己动手,但不要写它也可以作为一项微不足道的任务。
  • @a2h:嗯,我明白了。我没有意识到它有那么复杂。我只看了一眼网站,发现 wyUpdate 项目是开源的。我错过了您购买 wyBuild 以创建更新或晚上哭着入睡的部分。
  • 自己编写一个 good 自动更新程序可能比适应 wyupdate 或为其编写更新生成器需要更长的时间。我为我的一个项目写了一个糟糕的,我不会再这样做了。有很多错误的地方。尤其是 vista+ 的安全性和匀场功能,让它变得很痛苦。
【解决方案2】:

早该更新了,哎呀!

但无论如何,我已经使用SparkleDotNET 有一段时间了,它的运行非常好。这里和那里有一些小错误,但我已经帮助解决了其中一些问题,希望我也能够摆脱其他错误:)

对于那些有时间运行 Visual Studio 的发布功能,并且其应用程序相对独立,并且不需要像在启动时启动这样的操作的人,我肯定会推荐 ClickOnce。 MetroTwit 使用它并且它有一个很好的应用内更新界面,所以它看起来很灵活(至少在一定程度上)。对于在启动时启动,可能这样做,但这样做的方法很老套,而且效果不佳。

【讨论】:

  • 除非我遗漏了什么,否则 SparkleDotNet 似乎被遗弃了;最后一次更新是 2011 年 :(
【解决方案3】:

您可以从GitHub 尝试 Autoupdater.NET,这是我自己开发的,它在我的应用程序中运行良好。您只需在代码中添加一行即可。此外,它是开源的,因此您可以随意修改和使用。

【讨论】:

  • 试试吧,它很简单,而且效果很好!伟大的项目!
【解决方案4】:

您甚至可以不开发外部应用程序,而是将其实现为您应用程序的模块,例如进入namespace Update,并使用动态程序集生成器生成一个exe,启动它并退出app main,更新完成后再次启动它。

还有一些info

【讨论】:

    【解决方案5】:

    还有DDay update,它是开源的,由我的一位客户使用。我们/他们主要在 Windows 服务的上下文中对它感兴趣,因为它可以很好地工作。

    【讨论】:

      【解决方案6】:

      如需更强大的解决方案,您可能需要查看Google Omaha。这就是 Chrome 使用的。当您的应用未运行时,您可以在后台获取应用内更新和自动更新。

      【讨论】:

        【解决方案7】:

        尝试使用 MD5-Update,它完全免费且简单,无需在您的应用中进行配置,只需添加库并发布文件。 https://github.com/jrz-soft-mx/MD5-Update/

        1.您需要一个带有 PHP 的 Web 服务器 来发布您的文件,请包含 updt.exe。

        2。添加 index.php 以生成更新文件列表。可在 github 存储库https://github.com/jrz-soft-mx/MD5-Update/blob/main/Tools/Tools.zip 上找到,使用此代码创建新应用。

        <?php
        $_dat = array();
        $_dir=new RecursiveDirectoryIterator(".");
        foreach (new RecursiveIteratorIterator($_dir) as $_itm) {
            $_fil = str_replace(".".DIRECTORY_SEPARATOR, "", $_itm);
            if(!is_dir($_fil) && $_fil != "index.php"){     
                $_dat[]=array('StrFil' => "$_fil", 'StrMd5' => strtoupper(md5_file($_fil)), 'lonSiz' => filesize($_fil));
            }
        }
        echo json_encode($_dat, JSON_UNESCAPED_UNICODE);
        ?>
        

        3.在您的项目中添加 nuget 存储库

        PM> Install-Package MD5.Update
        

        4.当您的应用加注星标时调用库,使用您的更新文件夹 url,更新所有文件并将您的新应用下载到 updt 文件夹中,以替换您的应用需要 updt.exe

        string strUrl = "http://yourdomain.com/app/";
        if (MD5Update.MD5Update.Check(strUrl, true))
        {
            Process.Start(AppDomain.CurrentDomain.BaseDirectory + @"updt.exe", AppDomain.CurrentDomain.FriendlyName + " " + Process.GetCurrentProcess().ProcessName);
            Application.Exit();
        }
        

        5. updt.exe 用于将当前应用程序替换为新的应用程序 updt 文件夹到应用程序。可在 github 存储库 https://github.com/jrz-soft-mx/MD5-Update/blob/main/Tools/Tools.zip 上找到,使用此代码创建新应用。

        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            List<string> lisArg = Environment.GetCommandLineArgs().ToList();
            if (lisArg.Count < 2)
            {
                MessageBox.Show("Please provide App Excutable Name and Procees name");
                Application.Exit();
                return;
            }
            string strAppName = lisArg[1];
            string strAppProcees = lisArg[2];
            Process[] lisPro = Process.GetProcessesByName(strAppProcees);
            foreach (Process Pro in lisPro)
            {
                if (Pro.Id != Process.GetCurrentProcess().Id)
                {
                    Pro.Kill();
                    Thread.Sleep(1000);
                }
            }
            string strAppMain = AppDomain.CurrentDomain.BaseDirectory + strAppName;
            string strAppUpdate = AppDomain.CurrentDomain.BaseDirectory + @"updt\" + strAppName;
            if (!File.Exists(strAppMain))
            {
                MessageBox.Show("App Excutable dosent exists");
                Application.Exit();
                return;
            }
            if (!File.Exists(strAppUpdate))
            {
                MessageBox.Show("App Excutable Updated dosent exists");
                Application.Exit();
                return;
            }
            File.Copy(strAppUpdate, strAppMain, true);
            long fileSize = 0;
            FileInfo currentFile = new FileInfo(strAppMain);
            while (fileSize < currentFile.Length)
            {
                fileSize = currentFile.Length;
                Thread.Sleep(1000);
                currentFile.Refresh();
            }
            Process.Start(strAppMain);
        }
        catch (Exception Ex)
        {
            MessageBox.Show("An error ocurred");
            File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + @"updt_" + DateTime.Now.ToString("yyyyMMddTHHmmss")  + " .txt", Ex.ToString());
            Application.Exit();
        }
        

        【讨论】:

        • 试试这个包,它很简单,效果很好。
        【解决方案8】:

        所有的人都是对的,特别是看看 abatishchev 的回复。但我认为其他一些事情需要那个人忘记它。尝试开发您的项目“模块化”。尽可能将它们的代码放在类库中。所以在修复操作期间替换其中一个。考虑一下数据库修复。有时您需要在数据库表中添加一列。什么你会为这些情况做些什么?

        a 开发了一个更新项目。在这方面,我有三种修复。 1-程序运行BUG,需要更换一个DDL文件 2-程序中的Bug,需要更新当前程序执行文件 3-错误或更改数据库并需要执行sql server查询

        在网络主机上的表格中,我放置了版本历史记录,并且每次我的应用程序开始检查新版本时。如果存在任何更新,请检查其类型并下载并执行适当的操作,具体取决于更新类型和参数

        祝你好运

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-12
          相关资源
          最近更新 更多