【原创】自动更新程序2--更新程序的主窗体(技术:spring.net+三层架构+webservice+IrisSkin2换肤)
上篇文章主要介绍了webservice的部署以及主要的代码,下面给大家贴上主程序的代码,并简单的讲解。主程序判断是否有更新时通过主程序目录下有一个update.ini文件内的version是否有变化,主要思路为判断客户端的version是否==服务器端webservice提取到的version的值,update.ini文件内容如下:
[update] version=20132103 //通过这个客户端的version于服务器端的version相比较,如果不等于则为更新 program=BJCreation.CallAppWindow.Windows.exe //主程序的目录,也就是谁要启动这个update.exe [webservice] url=http://localhost:1546/UpdateWeb/sxsUpdateWebService.asmx //这个就是webservice的地址 method=GetUpdateInfos //webservice的方法名
1、变量定义
//关闭进度条的委托 public delegate void CloseProgressDelegate(); public delegate void OnGoToShowLogDegate(); public delegate void OnGoTOShowRtbLogDelate(object message); //声明关闭进度条事件 public event CloseProgressDelegate CloseProgress; string serviceVersion; WebClient wc = null; IniClass ini; //ini文件的操作 string url;//获取下载地址 string[] zips;//获取升级压缩包 string zip = "";//当前正在下载的压缩包 string uploadLog = string.Empty; //更新日志 int zipsIndex = 0;//当前正在下载的zips下标 long preBytes = 0;//上一次下载流量 long currBytes = 0;//当前下载流量 private static int time = 3;//3秒自动退出,没有更新的话自动退出 string filePath = string.Empty;
2、构造函数
public FormUpdate() { InitializeComponent(); this.btnDownload.Enabled = false; ini = new IniClass(Application.StartupPath + @"\Update.ini"); Thread thread = new Thread(new ThreadStart(ThreadMethod)); thread.Start(); } /// <summary> /// 如果将更新程序放到根目录下面的子目录内,如Realeas/Update/update.exe,则启动时需要传递参数调用这个方法 /// 主程序的调用方式如下:process.start("update/update.exe","\""+Application.StartupPath+"\"");因为如果当前目录含有空格类似c:\programes files\程序1 这样的目录,用start方式启动不成功,必须要将start的参数2改为短文件名 或者直接加""的方式 /// 构造窗体 /// </summary> /// <param name="path"></param> public FormUpdate( string path ) { this.filePath = path; InitializeComponent(); this.btnDownload.Enabled = false; ini = new IniClass( Application.StartupPath + @"\Update.ini" ); Thread thread = new Thread( new ThreadStart( ThreadMethod ) ); thread.Start(); }
//通过多线程去处理webservice的读取,防止界面卡死。webservice调用使用了代理的方式,不用添加web引用WebServiceHelper是一个类,实现了webservice的调用。只需要将webservice地址和方法名传递过去即可实现。
void ThreadMethod() { try { string webServiceUrl = ini.IniReadValue("webservice", "url");//wsdl地址 string method = ini.IniReadValue("webservice", "method");// string[] strArray = (string[])WebServiceHelper.InvokeWebService(webServiceUrl, method, null);//调用webservice并返回结果 uploadLog = strArray[3]; zips = strArray[2].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); url = strArray[1]; string clentVersion = ini.IniReadValue("update", "version"); serviceVersion = strArray[0];//服务端版本 if (!string.Equals(clentVersion, serviceVersion)) {//如果不等则直接显示更新日志及更新列表 OnGoToShowLogDegate logHandler = new OnGoToShowLogDegate(ShowLog); this.Invoke(logHandler); } else { OnGoToShowLogDegate logHandler = new OnGoToShowLogDegate(ShowRtbLogView); this.Invoke(logHandler); } } catch (Exception ex) { OnGoTOShowRtbLogDelate logHandler = new OnGoTOShowRtbLogDelate(ShowRtbLog); this.Invoke(logHandler, new object[] { ex.Message }); } }
更新程序首页日志的展示
void ShowLog() { this.groupBox1.Text = serviceVersion + "更新日志"; this.rtbUpdateLog.Text = string.IsNullOrEmpty(uploadLog) ? "暂时无更新" : uploadLog; if (zips.Length > 0) { foreach (string item in zips) { string size = ""; try { HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(new Uri(url + item)); HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse(); size = GetFileSize(myRes.ContentLength); myRes.Close(); } catch (Exception) { //如果有异常则不处理 } ListViewItem lsv = new ListViewItem(); lsv.Text = item; lsv.SubItems.Add(size); this.lsvFiles.Items.Add(lsv); } this.btnDownload.Enabled = true; } } private string GetFileSize(long size) { string msg = "0B"; if (size == 0) { } else if (size > 0 && size < 1024) { msg = size + "B"; } else if (size > 1024 && size < 1024 * 1024) { msg = (size / 1024) + "KB"; } else if (size > 1024 * 1024 && size < 1024 * 1024 * 1024) { msg = size / (1024 * 1024) + "MB"; } return msg; }
下面的是下载和解压的步骤
/// <summary> /// 下载更新 /// </summary> private void DownLoad() { try { CloseProgress += new CloseProgressDelegate(FrmUpdate_CloseProgress); if (zips.Length > 0) { wc = new WebClient(); wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); wc.DownloadFileAsync(new Uri(url + zips[zipsIndex]), zips[zipsIndex]); } else { FrmUpdate_CloseProgress();//调用关闭进度条事件 } } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// 下载完成后触发 /// </summary> void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { try { if (zipsIndex < zips.Length) { //继续下载下一个压缩包 wc = new WebClient(); wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); string url2 = url + zips[zipsIndex]; wc.DownloadFileAsync(new Uri(url2), zips[zipsIndex]); } else { //解压 string _path = string.IsNullOrEmpty(filePath) ? Application.StartupPath : filePath; int maximum = ZipClass.GetMaximum(zips, _path); foreach (string zip in zips) { string fileName = _path + @"\" + zip; string extension = Path.GetExtension(fileName); if (extension != ".zip") { //如果不是zip的文件则不允许解压。 continue; } ZipClass.UnZip(_path + @"\" + zip, "", maximum, FrmUpdate_SetProgress); File.Delete(_path + @"\" + zip); } FrmUpdate_CloseProgress();//调用关闭进度条事件 } //此行放置在此处 zipsIndex++; } catch (Exception ex) { Log.LogToFile(ex.Message); } } /// <summary> /// 下载时触发 /// </summary> void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { if (this.InvokeRequired) { this.Invoke(new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged), new object[] { sender, e }); } else { try { lblMessage.Text = "正在下载自解压包 " + zips[zipsIndex] + "(" + (zipsIndex + 1).ToString() + "/" + zips.Length + ")"; progressBar1.Maximum = 100; progressBar1.Value = e.ProgressPercentage; currBytes = e.BytesReceived;//当前下载流量 } catch (Exception) { //如果出错,直接运行。 } } } /// <summary> /// 解压时进度条事件 /// </summary> /// <param name="maximum">进度条最大值</param> private void FrmUpdate_SetProgress(int maximum, string msg) { if (this.InvokeRequired) { this.Invoke(new ZipClass.SetProgressDelegate(FrmUpdate_SetProgress), new object[] { maximum, msg }); } else { timer1.Enabled = false; //this.Text = "升级"; if (zipsIndex == zips.Length) { //刚压缩完 progressBar1.Value = 0; zipsIndex++; } lblMessage.Text = "正在解压" + msg + "(" + (progressBar1.Value + 1).ToString() + "/" + maximum + ")"; progressBar1.Maximum = maximum; progressBar1.Value++; } }
网上客户端升级源码下载 ----该程序是由网上的程序修改而来,大家有兴趣可以看看
UpdateWeb的源码下载(需要的可以研究一下,Bin下面有打包好的real)
更新主程序下载(此程序只包含有windows程序,如果报错自行引用Bin目录下面的dll即可。)
如果需要对Update.exe程序进行调用则直接书写
Process _process = new Process(); _process.StartInfo.FileName = "Update/BJCreation.AutoUpdate.Windows.exe"; _process.StartInfo.Arguments="\""+ Application.StartupPath+"\""; _process.StartInfo.WorkingDirectory =Application.StartupPath; _process.Start();
如果将Update.exe放在根目录下,则直接
Process.Start("Update.exe");即可