c#自动更新+安装程序的制作

一、自动更新的实现

让客户端实现自动更新,通常做法是在客户端部署一个单独的自动更新程序。主程序启动后,访问服务端,检查配置文件是否有更新版本,有更新版本就启动更新程序,由更新负责下载更新版本,并更新客户端程序,流程如下:

当流程进行到红色部分的是后就调用更新程序进行更新。

1)版本判断:

客户端和服务端都部署同一个版本文件,客户端登陆时发送验证给服务端判断版本是否一致。

Version.xml代码

""*@domcool.local/updater" type="get"id="508f3e88-4bb0-4585-a5c6-cc41ef57fef3"> <""2009-09-22"fileUrl="(0922).zip <">""></x> </query></iq>版本文件主要比较服务端Version.xml文件和客户端Version.xml文件中Version(版本号)是否一致,如果服务端Version属性大于客户端的Version属性,则通过服务端的fileUrl属性获取新版本的下载地址。供更新程序使用。2)删除原有更新包所有客户端更新文件均下载到C:\Documents and Settings\当前用户名\Local Settings\Temp 文件夹内,当客户端运行后首先判断是否有新更新包需要下载,如果没有则判断该临时文件夹内是否有旧有安装文件,如果存在,则删除旧有安装文件。private void RemoveOldSetupFile() {try{string temp = System.Environment.GetEnvironmentVariable("TEMP");string folder = new DirectoryInfo(temp).FullName;if (File.Exists(folder + @"\&; + setupName + ".exe")){File.Delete(folder + @"\&; + setupName + ".exe");}if (File.Exists(folder + @"\&; + setupName + ".msi")){File.Delete(folder + @"\&; + setupName + ".msi");}}catch { } }

备注:关于获取系统特殊文件夹的方法见博客

3)启动下载程序

下载程序和客户端程序是相互独立的,可以通过客户端开启新线程启动下载程序。下载程序在文件下载结束后可以关掉客户端程序,并开启新线程启动安装程序进行安装。

private void Update(){if (ShouldUpdate(query.Version, this.version)){MessageBox.Show("请更新客户端文件到版本[" + query.Version + "]", "更新提示", MessageBoxButtons.OK,MessageBoxIcon.Asterisk);System.Diagnostics.Process.Start(Application.StartupPath + @"\AutoUpdater.exe", query.FileUrl);}else { RemoveOldSetupFile(); }}private bool ShouldUpdate(string serverVersion, string localVersion){if (!string.IsNullOrEmpty(serverVersion) && !string.IsNullOrEmpty(localVersion)){return serverVersion.CompareTo(localVersion) > 0;}return true;}调用AutoUpdater.exe文件时需要传入文件下载地址。System.Diagnostics.Process.Start(Application.StartupPath + @"\AutoUpdater.exe", query.FileUrl);4)下载程序代码下载程序界面using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Net;using System.IO;using System.Threading;using System.Diagnostics;namespace AutoUpdater{public partial class MainForm : Form{private WebClient client;private string URl;private string fileName;private string path;private const string applicationFile = "Setup";public MainForm(string url){InitializeComponent();this.URl = url;client = new WebClient();client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);client.Proxy = WebRequest.DefaultWebProxy;client.Proxy.Credentials = new NetworkCredential();this.Hide();//Thread thread = new Thread(UpdateFile);//Thread.Sleep(15000);//thread.Start();UpdateFile();}public MainForm(){InitializeComponent();}/// <summary>/// 下载完成调用/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e){label1.Text = "文件接收完成";UnZip();RunUpdate();}/// <summary>/// 下载进度条/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){this.progressBar1.Value = e.ProgressPercentage;}/// <summary>/// 开始下载/// </summary>private void StartDownload(){fileName = URl.Substring(URl.LastIndexOf("/") + 1, URl.Length – URl.LastIndexOf("/") – 1);path = GetTempFolder();try{WebRequest myre = WebRequest.Create(URl);}catch (Exception ex){MessageBox.Show(ex.Message, "Error");}try{label1.Text = "开始下载文件…";client.DownloadFileAsync(new Uri(URl), path + @"\&; + fileName);}catch (WebException exp){label1.Text = exp.Message;}}/// <summary>/// 解压压缩包,格式必须是*.zip,否则不能解压/// 因为是调用Windows内部api进行解压,只能够识别zip压缩包/// 必须添加C:\WINDOWS\system32\shell32.dll的引用/// </summary>private void UnZip(){try{Shell32.ShellClass sc = new Shell32.ShellClass();Shell32.Folder SrcFolder = sc.NameSpace(this.path + @"\&; + this.fileName);Shell32.Folder DestFolder = sc.NameSpace(this.path);Shell32.FolderItems items = SrcFolder.Items();DestFolder.CopyHere(items, 20);}catch (Exception ex){MessageBox.Show(ex.Message);}}/// <summary>/// 获取下载文件夹地址及解压文件存放地址/// 此地址默认为C:\Documents and Settings\当前用户名\Local Settings\Temp 文件夹/// </summary>/// <returns></returns>private string GetTempFolder(){string folder = System.Environment.GetEnvironmentVariable("TEMP");return new DirectoryInfo(folder).FullName;}/// <summary>/// 开始下载文件/// </summary>private void UpdateFile(){this.Hide();//如果临时文件夹存在setup安装文件,就直接调用安装文件if (File.Exists(GetTempFolder() + @"\&; + applicationFile + ".exe") && File.Exists(GetTempFolder() +@"\&; + applicationFile + ".msi")){label1.Text = "开始下载文件…";this.progressBar1.Value = this.progressBar1.Maximum;label1.Text = "文件接收完成";RunUpdate();}//如果临时文件夹不存在setup安装文件,就从网络下载else{RemoveSetupFile();StartDownload();}}/// <summary>/// 清除旧有已下载的安装文件/// </summary>private static void RemoveSetupFile(){try{string temp = System.Environment.GetEnvironmentVariable("TEMP");string folder = new DirectoryInfo(temp).FullName;if (File.Exists(folder + @"\&; + applicationFile + ".exe")){File.Delete(folder + @"\&; + applicationFile + ".exe");}if (File.Exists(folder + @"\&; + applicationFile + ".msi")){File.Delete(folder + @"\&; + applicationFile + ".msi");}}catch { }}/// <summary>/// 下载完毕,开始执行更新程序/// </summary>private void RunUpdate(){try{foreach (Process p in Process.GetProcesses()){if (p.ProcessName.ToLower().StartsWith("uccompanion")){if (MessageBox.Show("UCCompanion正在运行,是否关闭当前程序安装更新?", "安装UCCompanion",MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes){p.Kill();Process.Start(GetTempFolder() + @"\&; + applicationFile + ".exe");}else{MessageBox.Show("UCCompanion下载完成,将在下次启动时提醒更新!");}}}}catch (Exception ex){MessageBox.Show(ex.Message);}finally{this.Close();}}/// <summary>/// 重载WindProc判断点击关闭按钮(X)时,隐藏程序界面/// </summary>/// <param name="msg"></param>protected override void WndProc(ref Message msg){const int WM_SYSCOMMAND = 0x0112;const int SC_CLOSE = 0xF060;if (msg.Msg == WM_SYSCOMMAND && ((int)msg.WParam == SC_CLOSE)){this.Hide();return;}base.WndProc(ref msg);}/// <summary>/// 双击图标弹出界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void icon_notify_MouseDoubleClick(object sender, MouseEventArgs e){this.Show();this.WindowState = FormWindowState.Normal;}/// <summary>////// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void MainForm_SizeChanged(object sender, EventArgs e){if (this.WindowState == FormWindowState.Minimized){this.Hide();}}private void MainForm_Load(object sender, EventArgs e){this.Hide();}}static class Program{/// <summary>/// 启动,接收传入网址作为参数/// </summary>/// <param name="agr"></param>[STAThread]static void Main(string[] agr){if (agr.Length == 1 && agr[0].StartsWith(@"")){MainForm form = new MainForm(agr[0]);Application.Run(form);}}}}

程序代码

将AutoUpdater项目生成的文件添加到客户端文件中,在客户端的Update()方法里调用updater,实现更新文件的下载。

以上就已经实现了自动更新功能,下面将讨论文件安装包的制作。

二、安装包的制作

1)创建安装项目

2)鼠标右击Setup项目选择>视图,可以看到制作安装包常见的视图有以下几个

最常用的视图有“文件系统”,“用户界面”和“启动条件”。

3)指定安装属性

鼠标左键单击项目名称,记住是左键单击,然后点击属性标签,注意:不是右击的属性

a.需要注意的是Version属性,每次版本更新时Version值必须后面的版本大于前面的版本。每次更改Version值时Projectcode会更改一次。

美不美乡中水,亲不亲故乡人。

c#自动更新+安装程序的制作

相关文章:

你感兴趣的文章:

标签云: