日期:2014-05-17  浏览次数:20846 次

c# 智能升级程序代码(2)

最主要的就是Update()这个函数了。当程序调用au.Update时,首先检查当前是否开户了自动更新:
if (!config.Enabled)
??? return;

如果启用了自动更新,就需要去下载服务器配置文件了:
WebClient client = new WebClient();
string strXml = client.DownloadString(config.ServerUrl);

然后,解析服务器配置文件到一个Dictionary中:

Dictionary<string, RemoteFile> listRemotFile = ParseRemoteXml(strXml);

接下来比较服务器配置文件和本地配置文件,找出需要下载的文件和本地需要删除的文件:

List<DownloadFileInfo> downloadList = new List<DownloadFileInfo>();
//某些文件不再需要了,删除
List<LocalFile> preDeleteFile = new List<LocalFile>();

foreach (LocalFile file in config.UpdateFileList)
{
??? if (listRemotFile.ContainsKey(file.Path))
??? {
??????? RemoteFile rf = listRemotFile[file.Path];
??????? if (rf.LastVer != file.LastVer)
??????? {
??????????? downloadList.Add(new DownloadFileInfo(rf.Url, file.Path, rf.LastVer, rf.Size));
??????????? file.LastVer = rf.LastVer;
??????????? file.Size = rf.Size;

??????????? if (rf.NeedRestart)
??????????????? bNeedRestart = true;
??????? }

??????? listRemotFile.Remove(file.Path);
??? }
??? else
??? {
??????? preDeleteFile.Add(file);
??? }
}

foreach (RemoteFile file in listRemotFile.Values)
{
??? downloadList.Add(new DownloadFileInfo(file.Url, file.Path, file.LastVer, file.Size));
??? config.UpdateFileList.Add(new LocalFile(file.Path, file.LastVer, file.Size));

??? if (file.NeedRestart)
??????? bNeedRestart = true;
}

如果发现有需要下载的文件,则向用户显示这些文件,并提示其是否马上更新。如果用户选择了马上更新,则先删除本地不再需要的文件,然后开始下载更新文件。
if (downloadList.Count > 0)
{
??? DownloadConfirm dc = new DownloadConfirm(downloadList);

??? if (this.OnShow != null)
??????? this.OnShow();

??? if (DialogResult.OK == dc.ShowDialog())
??? {
??????? foreach (LocalFile file in preDeleteFile)
??????? {
??????????? string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, file.Path);
??????????? if (File.Exists(filePath))
??????????????? File.Delete(filePath);

??????????? config.UpdateFileList.Remove(file);
??????? }

??????? StartDownload(downloadList);
??? }
}

我们再来看一下StartDownload函数

private void StartDownload(List<DownloadFileInfo> downloadList)
{
??? DownloadProgress dp = new DownloadProgress(downloadList);
??? if (dp.ShowDialog() == DialogResult.OK)
??? {
??????? //更新成功
??????? config.SaveConfig(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FILENAME));

??????? if (bNeedRestart)
??????? {
??????????? MessageBox.Show("程序需要重新启动才能应用更新,请点击确定重新启动程序。", "自动更新", MessageBoxButtons.OK, MessageBoxIcon.Information);
??????????? Process.Start(Application.ExecutablePath);
??????????? Environment.Exit(0);
??????? }
??? }
}

在这个函数中,先调用DownloadProgress下载所有需要下载的文件,然后更新本地配置文件,最后,如果发现某些更新文件需要重新启动应用程序的话,会提示用户重新启动程序。

至此,AutoUpdater这个类的使命就完成了,其实,整个的升级过程也就完成了。(废话)。

最后,我们来看一下这个组件是如何下载更新文件的

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.IO;
using System.Diagnostics;

namespace Iyond.Utility
{
??? public partial class DownloadProgress : Form
??? {
??????? private bool isFinished = false;
??????? private List<DownloadFileInfo> downloadFileList = null;
??????? private ManualResetEvent evtDownload = null;
??????? private ManualResetEvent evtPerDonwload = null;
??????? private WebClient clientDownload = null;

??????? public DownloadProgress(List<DownloadFileInfo> downloadFileList)
??????? {
??????????? InitializeComponent();

??????????? this.downloadFileList = downloadFileList;
??????? }

??????? private void OnFormClosing(object sender, FormClosingEventArgs e)
??????? {
???????