最近在做开发的时候,需要程序有自动版本升级的功能。特此记录下整个过程。
注意事项:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.NET;
using System.Xml;
namespace Update
{
///
/// 更新完成触发的事件
///
public delegate void UpdateState();
///
/// 程序更新
///
public class SoftUpdate
{
private string download;
private const string updateUrl = "http://www.csdn.Net/update.xml";//升级配置的XML文件地址
#region 构造函数
public SoftUpdate() { }
///
/// 程序更新
///
/// 要更新的文件
public SoftUpdate(string file,string softName) {
this.LoadFile = file;
this.SoftName = softName;
}
#endregion
#region 属性
private string loadFile;
private string newVerson;
private string softName;
private bool isUpdate;
///
/// 或取是否需要更新
///
public bool IsUpdate
{
get
{
checkUpdate();
return isUpdate;
}
}
///
/// 要检查更新的文件
///
public string LoadFile
{
get { return loadFile; }
set { loadFile = value; }
}
///
/// 程序集新版本
///
public string NewVerson
{
get { return newVerson; }
}
///
/// 升级的名称
///
public string SoftName
{
get { return softName; }
set { softName = value; }
}
#endregion
///
/// 更新完成时触发的事件
///
public event UpdateState UpdateFinish;
private void isFinish() {
if(UpdateFinish != null)
UpdateFinish();
}
///
/// 下载更新
///
public void Update()
{
try
{
if (!isUpdate)
return;
WebClient wc = new WebClient();
string filename = "";
string exten = download.Substring(download.LastIndexOf("."));
if (loadFile.IndexOf(@"/") == -1)
filename = "Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;
else
filename = Path.GetDirectoryName(loadFile) + "//Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;
wc.DownloadFile(download, filename);
wc.Dispose();
isFinish();
}
catch
{
throw new Exception("更新出现错误,网络连接失败!");
}
}
///
/// 检查是否需要更新
///
public void checkUpdate()
{
try {
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(updateUrl);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(stream);
XmlNode list = xmlDoc.SelectSingleNode("Update");
foreach(XmlNode node in list) {
if(node.Name == "Soft" && node.Attributes["Name"].Value.ToLower() == SoftName.ToLower()) {
foreach(XmlNode xml in node) {
if(xml.Name == "Verson")
newVerson = xml.InnerText;
else
download = xml.InnerText;
}
}
}
Version ver = new Version(newVerson);
Version verson = Assembly.LoadFrom(loadFile).GetName().Version;
int tm = verson.CompareTo(ver);
if(tm >= 0)
isUpdate = false;
else
isUpdate = true;
}
catch(Exception ex) {
throw new Exception("更新出现错误,请确认网络连接无误后重试!");
}
}
///
/// 获取要更新的文件
///
///
public override string ToString()
{
return this.loadFile;
}
}
}
下面是更新的XML文件类容,传到服务器上就可以了,得到XML文件的地址。
<Update>
<Soft Name="BlogWriter">
<Verson>1.0.1.2Verson>
<DownLoad>http://www.csdn.net/BlogWrite.rarDownLoad>
Soft>
Update>
程序更新调用方法如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;
using System.Xml;
using Update;
namespace UpdateTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkUpdate();
}
public void checkUpdate()
{
SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "BlogWriter");
app.UpdateFinish += new UpdateState(app_UpdateFinish);
try
{
if (app.IsUpdate && MessageBox.Show("检查到新版本,是否更新?", "Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
Thread update = new Thread(new ThreadStart(app.Update));
update.Start();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void app_UpdateFinish()
{
MessageBox.Show("更新完成,请重新启动程序!", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
如果需要异步下载并且显示下载进度信息,可以按照如下函数进行修改
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Wolfy.DownLoad
{
public partial class MainFrm : Form
{
private string _saveDir;
public MainFrm()
{
InitializeComponent();
_saveDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "download");
}
private void MainFrm_Load(object sender, EventArgs e)
{
if (!Directory.Exists(_saveDir))
{
Directory.CreateDirectory(_saveDir);
}
}
private void btnDownLoad_Click(object sender, EventArgs e)
{
string imageUrl = "http://image.3761.com/nvxing/2016022921/2016022921382152113.jpg";
string fileExt = Path.GetExtension(imageUrl);
string fileNewName = Guid.NewGuid() + fileExt;
bool isDownLoad = false;
string filePath = Path.Combine(_saveDir, fileNewName);
if (File.Exists(filePath))
{
isDownLoad = true;
}
var file = new FileMessage
{
FileName = fileNewName,
RelativeUrl = "nvxing/2016022921/2016022921382152113.jpg",
Url = imageUrl,
IsDownLoad = isDownLoad,
SavePath = filePath
};
if (!file.IsDownLoad)
{
string fileDirPath = Path.GetDirectoryName(file.SavePath);
if (!Directory.Exists(fileDirPath))
{
Directory.CreateDirectory(fileDirPath);
}
try
{
WebClient client = new WebClient();
client.DownloadFileCompleted += client_DownloadFileCompleted;
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFileAsync(new Uri(file.Url), file.SavePath, file.FileName);
}
catch
{
}
}
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.UserState != null)
{
this.lblMessage.Text = e.UserState.ToString() + ",下载完成";
}
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.proBarDownLoad.Minimum = 0;
this.proBarDownLoad.Maximum = (int)e.TotalBytesToReceive;
this.proBarDownLoad.Value = (int)e.BytesReceived;
this.lblPercent.Text = e.ProgressPercentage + "%";
}
}
}
在这过程中还参考了别人的代码过程,以及B站课程
下载地址:https://gakkiwife.lanzoub.com/ix8rN06eqtde
c#的整体代码可以通过链接进行下载:
https://gakkiwife.lanzoub.com/iEc8u06eyfni
public delegate void UpdateState();
///
/// 更新完成时触发的事件
///
public event UpdateState UpdateFinish;
#调用触发事件
app.UpdateFinish += new UpdateState(app_UpdateFinish);
void app_UpdateFinish()
{
MessageBox.Show("下载完成,请点击进行安装!", "Update", MessageBoxButtons.OK,MessageBoxIcon.Information);
}
public SoftUpdate(string file, string softName)
{
this.LoadFile = file;
this.SoftName = softName;
}
///
/// 要检查更新的文件
///
public string LoadFile
{
get { return loadFile; }
set { loadFile = value; }
}
///
/// 升级的名称
///
public string SoftName
{
get { return softName; }
set { softName = value; }
}