C# 程序自動升級的代碼
自動更新的軟件的目的在于讓客戶不在為了尋找最新軟件花費時間。也不用去到開發商的網站上查找。客戶端的軟件自動會在程序啟動前查找服務器上最新的版本。 和自己當前軟件的版本比較,如果服務器的是最新版本。客戶端則進行自動下載、解壓、安裝。當然了下載是要有網絡的,并且用戶可以根據提示去完成操作。再也 不用為找不到最新版本的軟件而頭疼。下面是我的大體思路,已經得到了實現:
1、 寫一個webservice,提供一個獲取服務器xml中版本的數據的方法。|
<?xml version="1.0" encoding="utf-8" ?> <Content> <Project id="程序名稱" Edition="1.0"> </Project> </Content></pre> 2、 在WinForm應用程序啟動的時候,首先訪問webservice獲取服務器的xml中的版本號,然后獲取客戶端的xml中的版本號。將兩個版本號比較,若服務器中的版本號大,則提示提示可以在線更新應用程序。
3、 然后客戶端自動下載網絡上的zip壓縮包到本機的指定位置,進行自動解壓縮到安裝的目錄進行覆蓋。解壓縮完畢之后,用進程打開所解壓過的exe文件進行軟件安裝。同時關閉客戶端軟件所在的進程。
4、注意:升級程序和應用程序都是單獨的,應用程序在使用時不能對本身進行升級(覆蓋會失敗)。
具體代碼如下:
第一部分 應用程序如口Program:using System; using System.Collections.Generic; using System.Windows.Forms; using Medicine_ERP; using DevExpress.XtraEditors; using System.Xml; using Anshield_AutoFutures.BaseClase;namespace Anshield_AutoFutures { static class Program { private static void LoadMath() { //服務器上的版本號 string NewEdition = "1.0"; //應用程序中的版本號 string OldEdition = "1.0";
try { //服務器上的版本號 NewEdition = webserverClase.getCopyRightCode(); //獲取系統中xml里面存儲的版本號 String fileName = Application.StartupPath + "\\XMLEdition.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); XmlNode xn = xmlDoc.SelectSingleNode("Content"); XmlNodeList xnl = xn.ChildNodes; foreach (XmlNode xnf in xnl) { XmlElement xe = (XmlElement)xnf; if (xe.GetAttribute("id") == "jigou_plz") { OldEdition = xe.GetAttribute("Edition");//動態數組 } break; } double newE = double.Parse(NewEdition); double oldE = double.Parse(OldEdition); //比較兩個版本號,判斷應用程序是否要更新 if (newE > oldE) { //更新程序¨ DialogResult dr = XtraMessageBox.Show("發現新的版本是否要更新該軟件", "平浪舟現貨程序化交易--更新提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); if (dr == DialogResult.OK) { //打開下載窗口 // Application.Run(new DownUpdate()); //啟動安裝程序 System.Diagnostics.Process.Start(Application.StartupPath + @"\Upgrade_Form.exe"); Application.Exit(); } else { //若用戶取消,打開初始界面 anshield_Login login = new anshield_Login(); if (login.ShowDialog() == DialogResult.OK) { Application.Run(new Main_AutoFutures()); } } } else { //若服務器版本低于或相等客戶端,打開初始界面 anshield_Login login = new anshield_Login(); if (login.ShowDialog() == DialogResult.OK) { Application.Run(new Main_AutoFutures()); } } } catch { XtraMessageBox.Show("網絡鏈接失敗!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main() { //保證同時只有一個客戶端在運行 System.Threading.Mutex mutexMyapplication = new System.Threading.Mutex(false, "jigou_plz.exe"); if (!mutexMyapplication.WaitOne(100, false)) { XtraMessageBox.Show("程序" + Application.ProductName + "已經在運行!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //漢化 hugengyong hu = new hugengyong(); DevExpress.UserSkins.OfficeSkins.Register(); DevExpress.Skins.SkinManager.EnableFormSkins(); DevExpress.UserSkins.BonusSkins.Register(); LoadMath(); } } }
}
</pre> 第二部分:升級程序代碼如下:
//debug目錄,用于存放壓縮文件 string path = Application.StartupPath;private void btnDown_Click(object sender, EventArgs e) { string zipFile = path + @"\jigou_plz.zip"; //關閉原有的應用程序
killProess();btnDown.Enabled = false; button2.Enabled = false; //自動下載壓縮包,并且解壓,最后關閉當前進程,進行安裝 try { //下載自動更新 string downUrl = ConfigurationManager.ConnectionStrings["DownUrl"].ConnectionString.ToString().Trim(); if (!string.IsNullOrEmpty(downUrl)) { DownloadFile(downUrl, zipFile, progressBar1, label1); } else { MessageBox.Show("Config中的下載路徑配置錯誤!", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } catch { MessageBox.Show("當前沒有網絡或者文件地址不正確"); return; } //解a壓1 try { //關閉原有的應用程序 killProess(); //unCompressRAR(path, path, "setup.rar", true); BaseClase.Zip.UnZip(zipFile, path, "", true,true); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } if (MessageBox.Show("升級完成!,請重新登陸!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information) == DialogResult.OK) { FileInfo file = new FileInfo(path + @"\Anshield_AutoFutures.exe");//文件地址 if (file.Exists) { Process.Start(path + @"\Anshield_AutoFutures.exe"); } Application.Exit(); } } /// <summary> /// c#.net 下載文件 /// </summary> /// <param name="URL">下載文件地址</param> /// /// <param name="Filename">下載后的存放地址</param> /// <param name="Prog">用于顯示的進度條</param> /// public void DownloadFile(string URL, string filename, System.Windows.Forms.ProgressBar prog, System.Windows.Forms.Label label1) { float percent = 0; try { System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL); System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse(); long totalBytes = myrp.ContentLength; if (prog != null) { prog.Maximum = (int)totalBytes; } System.IO.Stream st = myrp.GetResponseStream(); System.IO.Stream so = new System.IO.FileStream(filename, System.IO.FileMode.Create); long totalDownloadedByte = 0; byte[] by = new byte[1024]; int osize = st.Read(by, 0, (int)by.Length); while (osize > 0) { totalDownloadedByte = osize + totalDownloadedByte; System.Windows.Forms.Application.DoEvents(); so.Write(by, 0, osize); if (prog != null) { prog.Value = (int)totalDownloadedByte; } osize = st.Read(by, 0, (int)by.Length); percent = (float)totalDownloadedByte / (float)totalBytes * 100; label1.Text = "下載進度" + percent.ToString() + "%"; System.Windows.Forms.Application.DoEvents(); //必須加注這句代碼,否則label1將因為循環執行太快而來不及顯示信息 } label1.Text = "下載完成。安裝中... ..."; so.Flush();//將緩沖區內在寫入到基礎流中 st.Flush();//將緩沖區內在寫入到基礎流中 so.Close(); st.Close(); } catch (System.Exception) { throw; } }
/// <summary> /// 關閉原有的應用程序 /// </summary> private void killProess() { this.label1.Text = "正在關閉程序...."; System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("Anshield_AutoFutures"); //關閉原有應用程序的所有進程 foreach (System.Diagnostics.Process pro in proc) { pro.Kill(); } } </pre> zip壓縮文件解壓方法類
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.IO.Compression; using ICSharpCode.SharpZipLib.Zip;namespace Upgrade_Form.BaseClase { class Zip {
/// <summary> /// 解壓縮一個 zip 文件。 /// </summary> /// <param name="zipedFile">zip文件路徑</param> /// <param name="strDirectory">解壓路徑</param> /// <param name="password">zip文件的密碼</param> /// <param name="overWrite">是否覆蓋已存在的文件。</param> /// <param name="delteFile">解壓后是否刪除文件</param> public static void UnZip(string zipedFile, string strDirectory, string password, bool overWrite,bool delteFile) { //路徑不存在則創建 if (Directory.Exists(strDirectory) == false) { Directory.CreateDirectory(strDirectory); } if (strDirectory == "") strDirectory = Directory.GetCurrentDirectory(); if (!strDirectory.EndsWith("\\")) strDirectory = strDirectory + "\\"; using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile))) { s.Password = password; ZipEntry theEntry; while ((theEntry = s.GetNextEntry()) != null) { string directoryName = ""; string pathToZip = ""; pathToZip = theEntry.Name; if (pathToZip != "") directoryName = Path.GetDirectoryName(pathToZip) + "\\"; string fileName = Path.GetFileName(pathToZip); Directory.CreateDirectory(strDirectory + directoryName); if (fileName != "") { if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName))) { using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName)) { int size = 2048; byte[] data = new byte[2048]; while (true) { size = s.Read(data, 0, data.Length); if (size > 0) streamWriter.Write(data, 0, size); else break; } streamWriter.Close(); } } } } s.Close(); } if (delteFile == true) { File.Delete(zipedFile); } } }
} </pre>