123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Net;
- using System.IO;
- using System.Diagnostics;
- using System.Windows.Forms;
- using System.Threading;
- using System.Runtime.InteropServices;
- using Microsoft.Win32;
- using System.Xml;
- using Ionic.Zip;
- using System.Net.Security;
- using System.Security.Cryptography.X509Certificates;
- using System.Collections;
- namespace MAutoUpdate
- {
- public class UpdateWork
- {
- public delegate void UpdateProgess(double data);
- public UpdateProgess OnUpdateProgess;
- string mainName;
- //临时目录(WIN7以及以上在C盘只有对于temp目录有操作权限)
- string tempPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), @"MAutoUpdate\temp\");
- string bakPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), @"MAutoUpdate\bak\");
- LocalInfo localInfo;
- Hashtable hashTable;
- public List<RemoteInfo> UpdateVerList { get; set; }
- public string programName { get; set; }
- public string subKey { get; set; }
- public int Type { get; set; }
- /// <summary>
- /// 初始化配置目录信息
- /// </summary>
- public UpdateWork(string _programName, string localAddress, string isClickUpdate, int _type, Hashtable ht)
- {
- hashTable = ht;
- Type = _type;
- //localInfo = new LocalInfo(localAddress);
- //Process cur = Process.GetCurrentProcess();
- //mainName = Path.GetFileName(cur.MainModule.FileName);
- programName = _programName;
- //创建备份目录信息
- //DirectoryInfo bakinfo = new DirectoryInfo(bakPath);
- //if (bakinfo.Exists == false)
- //{
- // bakinfo.Create();
- //}
- ////创建临时目录信息
- //DirectoryInfo tempinfo = new DirectoryInfo(tempPath);
- //if (tempinfo.Exists == false)
- //{
- // tempinfo.Create();
- //}
- //localInfo.LoadXml(_type);
- //UpdateVerList = GetServer(localInfo.ServerUpdateUrl);
- //CheckVer(localInfo.LocalVersion, localInfo.LocalIgnoreVersion, isClickUpdate);
- }
- //public bool Do()
- //{
- // KillProcessExist();
- // Thread.Sleep(400);
- // //更新之前先备份
- // Bak();
- // Thread.Sleep(400);
- // //备份结束开始下载东西
- // DownLoad();//下载更新包文件信息
- // Thread.Sleep(400);
- // //3、开始更新
- // Update();
- // Thread.Sleep(400);
- // Start();
- // Thread.Sleep(400);
- // return true;
- //}
- public bool Do()
- {
- KillProcessExist();
- Thread.Sleep(400);
- //更新之前先备份
- //备份结束开始下载东西
- //DownLoad();//下载更新包文件信息
- DownLoadInfo();
- Thread.Sleep(400);
- Start();
- Thread.Sleep(400);
- return true;
- }
- public void DownLoadInfo()
- {
- var url = AppDomain.CurrentDomain.BaseDirectory + @"Debug/";
- if (!Directory.Exists(url))
- {
- Directory.CreateDirectory(url);
- }
- foreach (var item in hashTable.Keys)
- {
- Stream stream = new MemoryStream();
- try
- {
- LogTool.AddLog("更新程序:下载更新包文件" + item);
- byte[] bs = Convert.FromBase64String(hashTable[item].ToString());
- stream.Read(bs, 0, bs.Length);
- using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + @"Debug/" + item.ToString(), FileMode.Create))
- {
- fs.Write(bs, 0, bs.Length);
- }
- //web.DownloadFile(hashTable[item].ToString(), AppDomain.CurrentDomain.BaseDirectory + @"Debug/" + item.ToString());
- //OnUpdateProgess?.Invoke(60 / UpdateVerList.Count);
- }
- catch (Exception ex)
- {
- LogTool.AddLog("更新程序:更新包文件" + item + "下载失败,本次停止更新,异常信息:" + ex.Message);
- throw ex;
- }
- finally
- {
- stream.Close();
- stream.Dispose();
- }
- }
- //using (WebClient web = new WebClient())
- //{
- // foreach (var item in hashTable.Keys)
- // {
- // try
- // {
- // LogTool.AddLog("更新程序:下载更新包文件" + item);
- // web.DownloadFile(hashTable[item].ToString(), AppDomain.CurrentDomain.BaseDirectory + @"Debug/" + item.ToString());
- // //OnUpdateProgess?.Invoke(60 / UpdateVerList.Count);
- // }
- // catch (Exception ex)
- // {
- // LogTool.AddLog("更新程序:更新包文件" + item + "下载失败,本次停止更新,异常信息:" + ex.Message);
- // throw ex;
- // }
- // }
- //}
- }
- public static byte[] HexStrTobyte(string hexString)
- {
- hexString = hexString.Replace(" ", "");
- if ((hexString.Length % 2) != 0)
- hexString += " ";
- byte[] returnBytes = new byte[hexString.Length / 2];
- for (int i = 0; i < returnBytes.Length; i++)
- returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 16);
- return returnBytes;
- }
- public void IgnoreThisVersion()
- {
- var item = UpdateVerList[UpdateVerList.Count - 1];
- localInfo.LocalIgnoreVersion = item.ReleaseVersion;
- localInfo.SaveXml();
- }
- /// <summary>
- /// 获取更新的服务器端的数据信息
- /// </summary>
- /// <param name="url">自动更新的URL信息</param>
- /// <returns></returns>
- private static List<RemoteInfo> GetServer(string url)
- {
- ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
- List<RemoteInfo> list = new List<RemoteInfo>();
- XmlReader xml = XmlReader.Create(url);
- XmlDocument xdoc = new XmlDocument();
- xdoc.Load(url);
- var root = xdoc.DocumentElement;
- var listNodes = root.SelectNodes("/ServerUpdate/item");
- foreach (XmlNode item in listNodes)
- {
- RemoteInfo remote = new RemoteInfo();
- foreach (XmlNode pItem in item.ChildNodes)
- {
- remote.GetType().GetProperty(pItem.Name).SetValue(remote, pItem.InnerText, null);
- }
- list.Add(remote);
- }
- return list;
- }
- private static bool RemoteCertificateValidate(
- object sender, X509Certificate cert,
- X509Chain chain, SslPolicyErrors error)
- {
- System.Console.WriteLine("Warning, trust any certificate");
- return true;
- }
- /// <summary>
- /// 下载方法
- /// </summary>
- private UpdateWork DownLoad()
- {
- //比如uri=http://localhost/Rabom/1.rar;iis就需要自己配置了。
- //截取文件名
- //构造文件完全限定名,准备将网络流下载为本地文件
- using (WebClient web = new WebClient())
- {
- foreach (var item in UpdateVerList)
- {
- try
- {
- LogTool.AddLog("更新程序:下载更新包文件" + item.ReleaseVersion);
- web.DownloadFile(item.ReleaseUrl, tempPath + item.ReleaseVersion + ".zip");
- OnUpdateProgess?.Invoke(60 / UpdateVerList.Count);
- }
- catch (Exception ex)
- {
- LogTool.AddLog("更新程序:更新包文件" + item.ReleaseVersion + "下载失败,本次停止更新,异常信息:" + ex.Message);
- throw ex;
- }
- }
- return this;
- }
- }
- /// <summary>
- /// 备份当前的程序目录信息
- /// </summary>
- private UpdateWork Bak()
- {
- try
- {
- LogTool.AddLog("更新程序:准备执行备份操作");
- DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
- foreach (var item in di.GetFiles())
- {
- if (item.Name != mainName)//当前文件不需要备份
- {
- File.Copy(item.FullName, bakPath + item.Name, true);
- }
- }
- //文件夹复制
- foreach (var item in di.GetDirectories())
- {
- if (item.Name != "bak" && item.Name != "temp")
- {
- CopyDirectory(item.FullName, bakPath);
- }
- }
- LogTool.AddLog("更新程序:备份操作执行完成,开始关闭应用程序");
- OnUpdateProgess?.Invoke(20);
- return this;
- }
- catch (Exception EX)
- {
- throw EX;
- }
- }
- private UpdateWork Update()
- {
- foreach (var item in UpdateVerList)
- {
- try
- {
- //如果是覆盖安装的话,先删除原先的所有程序
- if (item.UpdateMode == "Cover")
- {
- DelLocal();
- }
- string path = tempPath + item.ReleaseVersion + ".zip";
- using (ZipFile zip = new ZipFile(path))
- {
- LogTool.AddLog("更新程序:解压" + item.ReleaseVersion + ".zip");
- zip.ExtractAll(AppDomain.CurrentDomain.BaseDirectory, ExtractExistingFileAction.OverwriteSilently);
- LogTool.AddLog("更新程序:" + item.ReleaseVersion + ".zip" + "解压完成");
- ExecuteINI();//执行注册表等更新以及删除文件
- }
- localInfo.LastUdpate = item.ReleaseDate;
- localInfo.LocalVersion = item.ReleaseVersion;
- localInfo.SaveXml();
- }
- catch (Exception ex)
- {
- LogTool.AddLog("更新程序出现异常:异常信息:" + ex.Message);
- LogTool.AddLog("更新程序:更新失败,进行回滚操作");
- Restore();
- break;
- }
- finally
- {
- //删除下载的临时文件
- LogTool.AddLog("更新程序:删除临时文件" + item.ReleaseVersion);
- DelTempFile(item.ReleaseVersion + ".zip");//删除更新包
- LogTool.AddLog("更新程序:临时文件删除完成" + item.ReleaseVersion);
- }
- }
- OnUpdateProgess?.Invoke(98);
- return this;
- }
- private UpdateWork Start()
- {
- try
- {
- Process.Start(Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"Debug\", "EapForIdle.exe"));
- //CopyFile();
- //String[] StartInfo = UpdateVerList[UpdateVerList.Count - 1].ApplicationStart.Split(',');
- //if (StartInfo.Length > 0)
- //{
- // foreach (var item in StartInfo)
- // {
- // LogTool.AddLog("更新程序:启动" + item);
- // Process.Start(Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"Debug\", item));
- // }
- //}
- //OnUpdateProgess?.Invoke(100);
- return this;
- }
- catch(Exception ex)
- {
- LogTool.AddLog(ex.ToString());
- return this;
- }
- }
- public void CopyFile()
- {
- try
- {
- string sourceName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Local.xml");
- string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Debug");
- if (!Directory.Exists(folderPath))
- {
- Directory.CreateDirectory(folderPath);
- }
- string fileName = Path.GetFileName(sourceName);
- string targetPath = Path.Combine(folderPath, fileName);
- FileInfo file = new FileInfo(sourceName);
- if (file.Exists)
- {
- file.CopyTo(targetPath, true);
- }
- }
- catch (Exception ex)
- {
- LogTool.AddLog(ex.ToString());
- }
- }
- /// <summary>
- /// 文件拷贝
- /// </summary>
- /// <param name="srcdir">源目录</param>
- /// <param name="desdir">目标目录</param>
- private UpdateWork CopyDirectory(string srcdir, string desdir)
- {
- string folderName = srcdir.Substring(srcdir.LastIndexOf("\\") + 1);
- string desfolderdir = desdir + "\\" + folderName;
- if (desdir.LastIndexOf("\\") == (desdir.Length - 1))
- {
- desfolderdir = desdir + folderName;
- }
- string[] filenames = Directory.GetFileSystemEntries(srcdir);
- foreach (string file in filenames)// 遍历所有的文件和目录
- {
- if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
- {
- string currentdir = desfolderdir + "\\" + file.Substring(file.LastIndexOf("\\") + 1);
- if (!Directory.Exists(currentdir))
- {
- Directory.CreateDirectory(currentdir);
- }
- CopyDirectory(file, desfolderdir);
- }
- else // 否则直接copy文件
- {
- string srcfileName = file.Substring(file.LastIndexOf("\\") + 1);
- srcfileName = desfolderdir + "\\" + srcfileName;
- if (!Directory.Exists(desfolderdir))
- {
- Directory.CreateDirectory(desfolderdir);
- }
- File.Copy(file, srcfileName, true);
- }
- }
- return this;
- }
- /// <summary>
- /// 删除临时文件
- /// </summary>
- private UpdateWork DelTempFile(String name)
- {
- FileInfo file = new FileInfo(tempPath + name);
- file.Delete();
- return this;
- }
- /// <summary>
- /// 更新失败的情况下,回滚当前更新
- /// </summary>
- private UpdateWork Restore()
- {
- DelLocal();
- CopyDirectory(bakPath, AppDomain.CurrentDomain.BaseDirectory);
- return this;
- }
- /// <summary>
- /// 删除本地文件夹的文件
- /// </summary>
- private UpdateWork DelLocal()
- {
- DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
- foreach (var item in di.GetFiles())
- {
- if (item.Name != mainName)
- {
- if (item.Name == "Local.xml")
- {
- }
- else
- {
- File.Delete(item.FullName);
- }
- }
- }
- foreach (var item in di.GetDirectories())
- {
- if (item.Name != "bak" && item.Name != "temp")
- {
- item.Delete(true);
- }
- }
- return this;
- }
- /// <summary>
- /// 校验程序版本号
- /// </summary>
- /// <param name="LocalVer">当前本地版本信息</param>
- /// <returns></returns>
- private UpdateWork CheckVer(string LocalVer, string localIgnoreVer, string isClickUpdate)
- {
- string[] Local = LocalVer.Split('.');
- string[] LocalIgnore = localIgnoreVer.Split('.');
- List<RemoteInfo> list = new List<RemoteInfo>();
- List<RemoteInfo> listReal = new List<RemoteInfo>();
- foreach (var item in UpdateVerList)
- {
- string[] Remote = item.ReleaseVersion.Split('.');
- for (int i = 0; i < Local.Length; i++)
- {
- if (int.Parse(Local[i]) < int.Parse(Remote[i]))
- {
- list.Add(item);
- break;
- }
- else if (int.Parse(Local[i]) == int.Parse(Remote[i]))
- {
- continue;
- }
- else
- {
- break;
- }
- }
- }
- if (isClickUpdate == "0")
- {
- foreach (var item in list)
- {
- string[] Remote = item.ReleaseVersion.Split('.');
- for (int i = 0; i < LocalIgnore.Length; i++)
- {
- if (int.Parse(LocalIgnore[i]) < int.Parse(Remote[i]))
- {
- listReal.Add(item);
- break;
- }
- else if (int.Parse(LocalIgnore[i]) == int.Parse(Remote[i]))
- {
- continue;
- }
- else
- {
- break;
- }
- }
- }
- }
- else
- {
- listReal = list;
- }
- UpdateVerList = listReal;
- return this;
- }
- /// <summary>
- /// 更新配置信息
- /// </summary>
- private UpdateWork ExecuteINI()
- {
- DirectoryInfo TheFolder = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
- if (File.Exists(Path.Combine(TheFolder.FullName, "config.update")))
- {
- string[] ss = File.ReadAllLines(Path.Combine(TheFolder.FullName, "config.update"));
- Int32 i = -1;//0[regedit_del] 表示注册表删除‘1[regedit_add]表示注册表新增 2[file_del] 表示删除文件
- foreach (var s in ss)
- {
- String s1 = s.Trim();
- if (s1 == "[regedit_del]")
- {
- i = 0;
- }
- else if (s1 == "[regedit_add]")
- {
- i = 1;
- }
- else if (s1 == "[file_del]")
- {
- i = 2;
- }
- else
- {
- if (i == 0)
- {
- string[] tempKeys = s1.Split(',');
- DelRegistryKey(tempKeys[0], tempKeys[1]);
- }
- else if (i == 1)
- {
- string[] values = s1.Split('=');
- string[] tempKeys = values[0].Split(',');
- SetRegistryKey(tempKeys[0], tempKeys[1], values[1]);
- }
- else if (i == 2)
- {
- DelFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, s1));
- }
- }
- }
- DelFile(Path.Combine(TheFolder.FullName, "config.update"));
- }
- return this;
- }
- /// <summary>
- /// 删除文件
- /// </summary>
- private UpdateWork DelFile(string name)
- {
- if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name)))
- {
- FileInfo file = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name));
- file.Delete();
- }
- return this;
- }
- /// <summary>
- /// 校验当前程序是否在运行
- /// </summary>
- /// <param name="programName"></param>
- /// <returns></returns>
- public bool CheckProcessExist()
- {
- return Process.GetProcessesByName(programName).Length > 0 ? true : false;
- }
- /// <summary>
- /// 杀掉当前运行的程序进程
- /// </summary>
- /// <param name="programName">程序名称</param>
- public void KillProcessExist()
- {
- Process[] processes = Process.GetProcessesByName(programName);
- foreach (Process p in processes)
- {
- p.Kill();
- p.Close();
- }
- }
- #region 暂时没用,如果需要将本地版本放注册表的话 那是有用的
- /// <summary>
- /// 设置注册表值
- /// </summary>
- /// <param name="subKey"></param>
- /// <param name="key"></param>
- /// <param name="value"></param>
- private void SetRegistryKey(String subKey, String key, String value)
- {
- RegistryKey reg;
- RegistryKey reglocal = Registry.CurrentUser;
- reg = reglocal.OpenSubKey(subKey, true);
- if (reg == null)
- reg = reglocal.CreateSubKey(subKey);
- reg.SetValue(key, value, RegistryValueKind.String);
- if (reg != null)
- {
- reg.Close();
- }
- }
- private void DelRegistryKey(String subKey, String key)
- {
- RegistryKey reg;
- RegistryKey reglocal = Registry.CurrentUser;
- reg = reglocal.OpenSubKey(subKey, true);
- if (reg != null)
- {
- var res = reg.GetValue(key);
- if (res != null)
- {
- reg.DeleteValue(key);
- }
- }
- reg.Close();
- }
- #endregion
- }
- }
|