【问题标题】:How to automatically update an application without ClickOnce?如何在没有 ClickOnce 的情况下自动更新应用程序?
【发布时间】:2012-09-29 01:26:29
【问题描述】:

对于我正在进行的项目,我不能使用ClickOnce。我的老板希望程序看起来“真实”(使用安装程序等)。

我已经安装了Visual Studio 2012Professional,并且一直在使用InstallShield安装程序,它确实是很好的安装程序,但我不知道如何启用应用程序“自动更新”(即是,当它启动时,会检查以确保它使用的是最新版本)。

我被要求对代码进行微小的更改 - 将加法转换为减法,我真的不希望人们必须卸载旧版本,然后每次我都必须重新安装新版本像这样做一个小改动。

如何让应用程序检查更新并安装它们?或者这不可能(或不容易)?

【问题讨论】:

标签: c# deployment


【解决方案1】:

关于这个问题已经有很多问题了,所以我会向你推荐这些。

您要确保避免卸载需要的一件事是,您在每个版本中使用相同的升级代码,但更改产品代码。这些值位于 Installshield 项目属性中。

一些参考资料:

【讨论】:

  • 我已经尝试过 - 进入并更改产品代码。但是当我去重新安装时,它说它正在安装,但根本没有改变程序....有什么想法吗?谢谢:)
  • 哦,它似乎确实重新安装了它(几次),但从未更新我电脑上的文件
  • 已安装的版本是否使用与当前安装程序相同的升级代码完成?如果没有,您可能需要使用 Orca。另请参阅此问题:stackoverflow.com/q/11540520/161052
  • 它是一样的,是的。显然这是关于升级路径的问题 - 但由于我使用的是有限版本,我不确定我是否可以解决这个问题
  • 按照您的确切步骤似乎不起作用,它仍然只是安装第二个应用程序。呃最令人沮丧的事情
【解决方案2】:

我认为您应该在 codeplex.com 上查看以下项目 http://autoupdater.codeplex.com/

此示例应用程序是用 C# 开发的,作为项目名称为“AutoUpdater”的库。 DLL “AutoUpdater” 可用于 C# Windows 应用程序(WinForm 和 WPF)。

AutoUpdater 有一些特性:

  1. 易于实施和使用。
  2. 检查更新后应用程序自动重新运行。
  3. 更新过程对用户透明。
  4. 为避免使用多线程下载阻塞主线程。
  5. 能够升级系统以及自动更新程序。
  6. 在不同系统使用时无需更改的代码 可以在库中编译。
  7. 便于用户下载更新文件。

如何使用?

在您想要自动更新的程序中,您只需要在 Main 过程中调用 AutoUpdate 函数即可。自动更新功能将使用从网站/FTP 中的文件读取的版本来检查版本。如果程序版本低于读取的版本,则程序下载自动更新程序并启动它,函数返回 True,这意味着将运行自动更新并关闭当前程序。自动更新程序从要更新的程序接收几个参数并执行必要的自动更新,然后启动更新的系统。

  #region check and download new version program
  bool bSuccess = false;
  IAutoUpdater autoUpdater = new AutoUpdater();
  try
  {
      autoUpdater.Update();
      bSuccess = true;
  }
  catch (WebException exp)
  {
      MessageBox.Show("Can not find the specified resource");
  }
  catch (XmlException exp)
  {
      MessageBox.Show("Download the upgrade file error");
  }
  catch (NotSupportedException exp)
  {
      MessageBox.Show("Upgrade address configuration error");
  }
  catch (ArgumentException exp)
  {
      MessageBox.Show("Download the upgrade file error");
  }
  catch (Exception exp)
  {
      MessageBox.Show("An error occurred during the upgrade process");
  }
  finally
  {
      if (bSuccess == false)
      {
          try
          {
              autoUpdater.RollBack();
          }
          catch (Exception)
          {
             //Log the message to your file or database
          }
      }
  }
  #endregion

【讨论】:

    【解决方案3】:

    最常见的方法是将一个简单的文本文件(XML/JSON 更好)放在您的网络服务器上,并使用最后一个构建版本。然后应用程序将下载此文件,检查版本并启动更新程序。典型的文件如下所示:

    应用程序更新文件(让您的应用程序识别文件类型的唯一字符串

    版本:1.0.0(最新汇编版本

    下载:http://yourserver.com/...(下载版本的链接

    redirect:http://yournewserver.com/...(我使用这个字段以防服务器地址发生变化。

    这会让客户知道他们需要寻找一个新地址。

    您还可以添加其他重要的详细信息。

    【讨论】:

    • 这是有道理的。但是如何避免在重新安装时出现“该项目的另一个版本已安装....”的消息?
    • @JYelton 指出,保持相同的更新代码。还有其他方法,但我忘了:(
    【解决方案4】:

    外行人的方式是

    在 Main() 上将正在执行的程序集文件 .exe 重命名为其他名称 检查创建日期和时间。 和更新的文件日期时间并复制到应用程序文件夹中。

    //Rename he executing file
    System.IO.FileInfo file = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
    
    System.IO.File.Move(file.FullName, file.DirectoryName + "\\" + file.Name.Replace(file.Extension,"") + "-1" + file.Extension);
    

    然后进行逻辑检查并将新文件复制到执行文件夹

    【讨论】:

      【解决方案5】:

      这是更新文件但不安装的代码 该程序是通过dos制作的,用于将文件复制到最新日期并自动运行您的程序。可以帮到你

      打开记事本并使用 ext .bat 保存下面的文件

      xcopy \\IP address\folder_share_name\*.* /s /y /d /q  
      start "label" /b "youraplicationname.exe"
      

      【讨论】:

        【解决方案6】:

        如今,您可以使用 Windows 10 中包含的称为 AppInstaller 的应用交付机制,方法是将您的应用打包到 MSIX 包或包中。

        有了它,您不必考虑安装程序(如果您的应用不使用大量依赖项)、后台更新等等。它比 ClickOnce 好得多,由于别名,命令行使用就像一个魅力,更新是不突兀的,也可以用于后台应用程序。

        安装体验也更好:用户只需单击 HTML 上的按钮,Windows 就会自动安装应用程序。

        这不是超级简单,我会说比 ClickOnce 复杂,但没有 Wix 难。

        Official guide 不适用于 .NET Core 或 .NET 5 应用程序,因此您可以参考 this articlethis great video,例如。 This site 也包含很多有用的信息。

        【讨论】:

          【解决方案7】:

          使用 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();
          }
          

          【讨论】:

          • 试试这个包,它很简单,效果很好。
          猜你喜欢
          • 1970-01-01
          • 2023-01-05
          • 1970-01-01
          • 2017-02-02
          • 1970-01-01
          • 2017-07-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多