更新系统应用程序

时间:2014-04-22 14:21:54

标签: c# xml wpf updates

美好的一天。

我们正在使用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();
      }
    }
  }
}

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

2 个答案:

答案 0 :(得分:1)

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

我们的流程如下:

  1. 检查更新
  2. 下载更新zip
  3. 将所有文件重命名为* .old
  4. 将zip文件解压缩到应用程序位置
  5. 关闭(终止)并重新启动应用程序
  6. 启动时删除* .old文件
  7. 我们从未对此行为有任何问题,但您可能不想为应用程序实现mutex,因此您可以确保只有一个实例同时运行。

答案 1 :(得分:1)

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

启动更新程序后,Process.Start("Updater.exe");您需要退出当前进程并确保它根本不运行。您可以通过添加以下行来完成此操作:

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