更新系统应用程序

本文关键字:应用程序 系统 更新 | 更新日期: 2023-09-27 17:59:18

您好。

我们正在用WPF在C#的学校自助餐厅创建一个销售控制系统,该系统将在我们网络中的18所学校实施。(学校分散在城市各处,因此,系统更新将通过互联网自动进行)。

研究了ClickOnce(开发了类似的东西),我们知道这种类型的更新是不可行的。

我们使用DotNetZip API创建了一个系统更新,但在将文件保存到安装了系统文件的目录中时出现错误,原因是与其他问题不兼容。

我的问题如下:

有人在这方面有任何经验可以与我分享吗,或者有任何情况的例子(就像这样),这样我们就可以在我们的系统中应用了吗?

我将把更新系统以创建的代码片段放在这里,如果有人想要分析它,它将更容易理解问题。

此代码的逻辑搜索XML文件的可用系统版本,并将其与程序集的版本进行比较。如果版本更高,则向下到临时目录更新文件并传输到安装应用程序的目录。出现的问题是,某些类型的文件即使在与主应用程序一起完成后,看起来也像是在运行。

我很感激你的帮助。

调用更新程序的主窗体

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var doc = new XmlDocument();
    doc.Load("http://www.meusite.org.br/Cantina/arquivoXML.xml");
        if (doc.DocumentElement != null)
        {
            var node = doc.DocumentElement.SelectSingleNode("/Application/Version");
            var node1 = doc.DocumentElement.SelectSingleNode("/Application/ZipFile");
            if (node != null)
            {
                var version = node.InnerText;
                var versionAssembly =     System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
                if (Convert.ToDouble(version) > Convert.ToDouble(versionAssembly))
                {
                    Process.Start("Updater.exe");
                }
            }
        }
     }

更新程序系统:

using System.Diagnostics;
using Ionic.Zip;
using System.Xml;
using System.IO;

namespace Updater
{
public class Program
{
    private static void Main()
    {
   Process[] process = Process.GetProcessesByName("IASD.ASCS.WPF");
    foreach (Process proc in process)
    {
        if (!proc.HasExited)
            proc.Kill();
    }
    XmlDocument doc = new XmlDocument();
    doc.Load("http://www.meusite.org.br/Cantina/arquivoXML.xml");
    if (doc.DocumentElement != null)
    {
        XmlNode node1 = doc.DocumentElement.SelectSingleNode("/Application/ZipFile");
        if (node1 != null)
        {
            string zipfile = node1.InnerText;
            const string end = ("http://www.meusite.org.br/Cantina/");
            string file = (end + zipfile);
            ZipFile zipFile = ZipFile.Read(file);
            {
                foreach (var zipEntry in zipFile)
                {
                    zipEntry.Extract(@"c:'IASD'CantinaEscolar'Temp",ExtractExistingFileAction.OverwriteSilently);
                }
            }
            string dirTemp = @"c:'IASD'CantinaEscolar'Temp";
            string dirInstalacao = @"c:'IASD'CantinaEscolar'";
            string[] arquivos = Directory.GetFiles(dirTemp);
            foreach (string item in arquivos)
            {
                string nomedoarquivo = Path.GetFileName(item);
                if (nomedoarquivo != null)
                {
                    string destino = Path.Combine(dirInstalacao, nomedoarquivo);
                    File.Copy(item, destino, true);
                }
            }
            string[] arquivosApagar = Directory.GetFiles(dirTemp);
            foreach (string item in arquivosApagar)
            {
                File.Delete(item);
            }
            Process.Start("IASD.ASCS.WPF.exe");
        }
    }
    const string nomeExecutavel2 = "Updater.exe";
    foreach (Process pr2 in Process.GetProcessesByName(nomeExecutavel2))
      {
        if (!pr2.HasExited) pr2.Kill();
      }
    }
  }
}

在这个例子中,我正在确定系统将安装在哪个位置,但我是否需要向用户提供安装在您计算机上任何目录中的信息(这是我无法解决的另一个问题)。

更新系统应用程序

当您正在进行更新并且应用程序仍在运行时,您无论如何都可以进行更新,但您必须重命名所有文件,然后粘贴新文件。应用程序将保持正常运行,直到下一次应用程序重新启动。

我们的流程如下:

  1. 检查更新
  2. 下载更新zip
  3. 将所有文件重命名为*.old
  4. 将zip文件提取到应用程序位置
  5. 关闭(终止)并重新启动应用程序
  6. 启动时删除*.旧文件

我们从未遇到过这种行为的任何问题,但也许您不想为应用程序实现互斥,这样您就可以确保同时只有一个实例在运行。

在Window_Loaded事件中开始下载后,原始进程将继续运行。当下载程序尝试替换exe文件时,它使用的任何文件都将失败。

启动更新程序Process.Start("Updater.exe");后,您需要退出当前进程,并确保它根本没有运行。您可以添加以下行:

if (Convert.ToDouble(version) > Convert.ToDouble(versionAssembly))
{
    Process.Start("Updater.exe");
    Application.Exit(); // Assumes a WinForms app
}