using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using System.Windows.Threading; using System.Xml; namespace AutoUpdater { /// /// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { private enum Mode { Province, ServerPart, Shop, Machine } private enum Service { ServiceInstall, ServiceUpdate } private Mode IntConvertToEnumOther(int ModeKey) { return (Mode)ModeKey; } BackgroundWorker UpdateBackgroundWorker; Timer UpdateTimer = new Timer(); Dictionary ProgressList = new Dictionary(); DateTime UpdateStartTime { get; set; } int FileCount { get; set; } string UpdateUrl { get; set; } string UpdatePort { get; set; } string ServerPartCode { get; set; } string ShopCode { get; set; } string UpdateMode { get; set; } string IsNewSystem { get; set; } bool UpdateWorkerFlag { get; set; } bool DownFlag { get; set; } static string AppDir = AppDomain.CurrentDomain.BaseDirectory; string XMLPath = AppDir + "\\Update.xml"; string DownPath = AppDir + "\\UpdateFiles"; public MainWindow() { InitializeComponent(); UpdateWorkerFlag = false; DownFlag = false; MessageBeginInvoke("0", "downProgress", "ProgressBar"); UpdateStartTime = DateTime.Now; SoftNameLoading(); UpdateBackgroundWorker = new BackgroundWorker(); UpdateBackgroundWorker.DoWork += BackgroundWorker_DoWork; UpdateBackgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged; UpdateBackgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted; UpdateBackgroundWorker.WorkerReportsProgress = true; UpdateBackgroundWorker.WorkerSupportsCancellation = true; UpdateTimer.Elapsed += Timer_Tick; UpdateTimer.Interval = 300; UpdateTimer.Start(); } private void Timer_Tick(object sender, EventArgs e) { if (!UpdateBackgroundWorker.IsBusy && !UpdateWorkerFlag) { UpdateWorkerFlag = true; UpdateBackgroundWorker.RunWorkerAsync(); } if (ProgressList.Count > 0) { long _Progress = 0; foreach (string _Key in ProgressList.Keys) { _Progress += ProgressList[_Key]; } MessageBeginInvoke((_Progress / FileCount).ToString("F2"), "downProgress", "ProgressBar"); } else { if (UpdateStartTime == null) UpdateStartTime = DateTime.Now; TimeSpan _TimeSpan = DateTime.Now - UpdateStartTime; MessageBeginInvoke((_TimeSpan.TotalSeconds / 20 * 100).ToString("F2"), "downProgress", "ProgressBar"); if (_TimeSpan.TotalSeconds > 20) { EndUpdate("收银系统正在启动......"); } } } /// /// 初始化属性 /// private void InitializeAttribute() { UpdateUrl = Lib.ConfigHelper.GetAppConfig(XMLPath, "IP"); UpdatePort = Lib.ConfigHelper.GetAppConfig(XMLPath, "Port"); ServerPartCode = Lib.ConfigHelper.GetAppConfig(XMLPath, "ServerPartCode"); ShopCode = Lib.ConfigHelper.GetAppConfig(XMLPath, "ShopCode"); UpdateMode = Lib.ConfigHelper.GetAppConfig(XMLPath, "UpdateMode"); if (String.IsNullOrWhiteSpace(UpdateUrl) || String.IsNullOrWhiteSpace(UpdatePort) || String.IsNullOrWhiteSpace(ServerPartCode) || String.IsNullOrWhiteSpace(ShopCode) || String.IsNullOrWhiteSpace(UpdateMode)) { InitializeConfig(); } } /// /// 程序配置初始化 /// private void InitializeConfig() { try { if (String.IsNullOrWhiteSpace(UpdateUrl)) { UpdateUrl = Lib.Win32API.INIGetStringValue(AppDir + "\\setup.ini", "DBCONECT", "dbip", ""); } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "IP", UpdateUrl); if (String.IsNullOrWhiteSpace(UpdatePort)) { UpdatePort = "11000"; } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "Port", UpdatePort); if (String.IsNullOrWhiteSpace(Lib.ConfigHelper.GetAppConfig(XMLPath, "UpDate"))) { Lib.ConfigHelper.UpdateAppConfig(XMLPath, "UpDate", "2018/03/09 20:33:00"); } if (String.IsNullOrWhiteSpace(ServerPartCode)) { ServerPartCode = Lib.Win32API.INIGetStringValue(AppDir + "\\setup.ini", "DBCONECT", "serverpartcode", ""); } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "ServerPartCode", ServerPartCode); if (String.IsNullOrWhiteSpace(ShopCode)) { ShopCode = Lib.Win32API.INIGetStringValue(AppDir + "\\setup.ini", "DBCONECT", "shopcode", ""); } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "ShopCode", ShopCode); if (String.IsNullOrWhiteSpace(UpdateMode)) { UpdateMode = "2"; } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "UpdateMode", UpdateMode); if (String.IsNullOrWhiteSpace(IsNewSystem)) { IsNewSystem = "0"; } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "NewSystem", IsNewSystem); if (String.IsNullOrWhiteSpace(Lib.ConfigHelper.GetAppConfig(XMLPath, "SoftVersion"))) { Lib.ConfigHelper.UpdateAppConfig(XMLPath, "SoftVersion", FileVersionInfo.GetVersionInfo("cashier.exe").ProductVersion); } if (String.IsNullOrWhiteSpace(Lib.ConfigHelper.GetAppConfig(XMLPath, "SoftName"))) { Lib.ConfigHelper.UpdateAppConfig(XMLPath, "SoftName", Lib.Win32API.INIGetStringValue(AppDir + "\\setup.ini", "DBCONECT", "softwarename", "驿商统一收银系统")); } if (String.IsNullOrWhiteSpace(Lib.ConfigHelper.GetAppConfig(XMLPath, "KillApp"))) { Lib.ConfigHelper.UpdateAppConfig(XMLPath, "KillApp", "TouchCashier.exe|cashier.exe|Stardb.exe|" + "dbsyc.exe|GetMembership.exe|DataUpdate.exe|InvoicingTool.exe|ConnectPoint.exe"); } if (String.IsNullOrWhiteSpace(Lib.ConfigHelper.GetAppConfig(XMLPath, "StartApp"))) { if (IsNewSystem != "1") { string _StartApp = "Stardb.exe|cashier.exe"; if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "ConnectPoint.exe")) { _StartApp += (_StartApp == "" ? "" : "|") + "ConnectPoint.exe"; } if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "GetMembership.exe")) { _StartApp += (_StartApp == "" ? "" : "|") + "GetMembership.exe"; } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "StartApp", _StartApp); } else { string _StartApp = "Stardb.exe"; if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "ConnectPoint.exe")) { _StartApp += (_StartApp == "" ? "" : "|") + "ConnectPoint.exe"; } if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "TouchCashier.exe")) { _StartApp += (_StartApp == "" ? "" : "|") + "TouchCashier.exe"; } else { _StartApp += (_StartApp == "" ? "" : "|") + "cashier.exe"; } if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "GetMembership.exe")) { _StartApp += (_StartApp == "" ? "" : "|") + "GetMembership.exe"; } Lib.ConfigHelper.UpdateAppConfig(XMLPath, "StartApp", _StartApp); } } } catch { } } /// /// 主界面显示名称初始化 /// private void SoftNameLoading() { string _SoftName = Lib.ConfigHelper.GetAppConfig(XMLPath, "SoftName"); if (_SoftName == "") { _SoftName = "驿商统一收银系统"; Lib.ConfigHelper.UpdateAppConfig(XMLPath, "SoftName", "驿商统一收银系统"); } switch (_SoftName) { case "交投蜀越收银系统": MessageBeginInvoke("交投蜀越收银系统", "SoftName", "Label"); MessageBeginInvoke("Component/Image/四川.png", "Logo", "Image"); break; case "高速驿网收银系统": MessageBeginInvoke("高速驿网收银系统", "SoftName", "Label"); MessageBeginInvoke("Component/Image/浙江.png", "Logo", "Image"); break; case "贵州公路收银系统": MessageBeginInvoke("贵州公路收银系统", "SoftName", "Label"); MessageBeginInvoke("Component/Image/贵州公路.png", "Logo", "Image"); break; default: MessageBeginInvoke("驿商统一收银系统", "SoftName", "Label"); MessageBeginInvoke("Component/Image/驿商.png", "Logo", "Image"); break; } } private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { //线程报告 } private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //线程退出后操作 } private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { string _ServerDate = null; string _ServerVersion = null; string _LocalDate = null; bool _UpdateFalg = false; bool _FinishFalg = true; InitializeAttribute(); //通用更新地址 string _ServerXML = "http://" + UpdateUrl + ":" + UpdatePort + "/UpdateServer/UpdateList.xml"; string _WebServiceUri = "http://" + UpdateUrl + ":" + UpdatePort + "/Update.asmx"; //string _WebServiceUri = "http://localhost:5293/Update.asmx"; XmlDocument _XmlDoc = new XmlDocument(); MessageBeginInvoke("正在检查程序更新......", "lblMsg", "Label"); if (!int.TryParse(UpdateMode, out int _Mode)) { _Mode = 2; } try { //使用接口获取更新列表 if (_Mode == 3 || String.IsNullOrWhiteSpace(ServerPartCode) || String.IsNullOrWhiteSpace(ShopCode)) { string[] args = { IntConvertToEnumOther(_Mode).ToString(), Lib.PCHelper.GetMacAddressByNetworkInformation() }; _XmlDoc.LoadXml(Lib.WSHelper.InvokeWebService(_WebServiceUri, "POSUpdate", args).ToString()); } else { string[] args = { IntConvertToEnumOther(_Mode).ToString(), ServerPartCode + "," + ShopCode }; _XmlDoc.LoadXml(Lib.WSHelper.InvokeWebService(_WebServiceUri, "POSUpdate", args).ToString()); } } catch (Exception ex) { //try //{ // _XmlDoc.Load(_ServerXML); //} //catch //{ string _LocalUpdateList = DownPath + "\\Updatelist-" + Lib.ConfigHelper.GetAppConfig(XMLPath, "SoftVersion") + ".xml"; if (File.Exists(_LocalUpdateList)) { _XmlDoc.Load(_LocalUpdateList); } //} } try { _ServerDate = Lib.XMLHelper.GetXmlAttribute(_XmlDoc, "//UpdateInfo//UpdateTime", "Date").Value; } catch (Exception ex) { _ServerDate = Lib.ConfigHelper.GetAppConfig(XMLPath, "UpDate"); } try { _ServerVersion = Lib.XMLHelper.GetXmlAttribute(_XmlDoc, "//UpdateInfo//Version", "Num").Value; } catch (Exception ex) { _ServerVersion = Lib.ConfigHelper.GetAppConfig(XMLPath, "SoftVersion"); } if (!String.IsNullOrEmpty(_ServerDate) && _ServerDate != "") { _LocalDate = Lib.ConfigHelper.GetAppConfig(XMLPath, "UpDate"); if (String.IsNullOrEmpty(_LocalDate) || _LocalDate == "") { _UpdateFalg = true; } else { if (DateTime.Compare(Convert.ToDateTime(_ServerDate, CultureInfo.InvariantCulture), Convert.ToDateTime(_LocalDate, CultureInfo.InvariantCulture)) > 0) { _UpdateFalg = true; } } } try { if (_UpdateFalg) { MessageBeginInvoke("正在创建更新下载任务......", "lblMsg", "Label"); StartDownLoad(_XmlDoc, _ServerVersion, _ServerDate); } else { StartKillAPP(_XmlDoc); if (StartCheck(_XmlDoc, _ServerVersion, _ServerDate)) { EndUpdate("收银系统正在启动......"); } else { StartDownLoad(_XmlDoc, _ServerVersion, _ServerDate); } } } catch { StartKillAPP(_XmlDoc); EndUpdate("收银系统正在启动......"); } } /// /// 关闭已启动程序 /// /// 程序更新文件列表 private void StartKillAPP(XmlDocument XMLDoc) { string _FileName = ""; XmlNodeList xmlNodeList = XMLDoc.SelectNodes("//UpdateFileList//UpdateFile"); for (int i = 0; i < xmlNodeList.Count; i++) { _FileName = xmlNodeList[i].InnerXml.Substring(xmlNodeList[i].InnerXml.LastIndexOf("\\") + 1); if (_FileName.EndsWith(".rar")) { _FileName = _FileName.Substring(0, _FileName.LastIndexOf(".rar")); } if (_FileName.EndsWith(".exe")) { Lib.ProcessHelper.KillExe(_FileName); } } Lib.ProcessHelper.KillExe(Lib.ConfigHelper.GetAppConfig(XMLPath, "KillApp").Split('|')); System.Threading.Thread.Sleep(300); } /// /// 更新结束启动主程序 /// /// 启动过程显示的消息 private void StartSetupAPP(string Msg) { Process[] _ProcessList = Process.GetProcessesByName("dbsrv12"); if (_ProcessList.Count() == 0) { try { Process.Start(AppDomain.CurrentDomain.BaseDirectory + "dbsrv12.exe", "-os 10240k -m -c 8m -q -n " + Dns.GetHostName() + " -x tcpip{port=3362} " + AppDomain.CurrentDomain.BaseDirectory + "datebase\\hydb.db"); } catch { } } string[] _APPList = Lib.ConfigHelper.GetAppConfig(XMLPath, "StartApp").Split('|'); for (int i = 0; i < _APPList.Length; i++) { decimal _Progress = (decimal)(i + 1) / _APPList.Length * 100; MessageBeginInvoke(Msg, "lblMsg", "Label"); MessageBeginInvoke(_Progress.ToString("F2"), "downProgress", "ProgressBar"); Lib.ProcessHelper.StartProc(_APPList[i]); System.Threading.Thread.Sleep(50); } //StartProc(_APPList); } /// /// 检验指定列表文件MD5并进行修复 /// /// 文件列表 /// 程序版本 /// 更新日期 /// 返回结果 private bool StartCheck(XmlDocument XMLDoc, string APPVersion, string UpdateDate) { string _FileName = ""; XmlNodeList xmlNodeList = XMLDoc.SelectNodes("//UpdateFileList//UpdateFile"); for (int i = 0; i < xmlNodeList.Count; i++) { decimal _Progress = (decimal)(i + 1) / xmlNodeList.Count * 100; MessageBeginInvoke("正在校验程序完整性......(" + _Progress.ToString("F0") + "%)", "lblMsg", "Label"); MessageBeginInvoke(_Progress.ToString("F2"), "downProgress", "ProgressBar"); if (xmlNodeList[i].InnerXml.EndsWith(".rar")) { _FileName = xmlNodeList[i].InnerXml.Substring(xmlNodeList[i].InnerXml.LastIndexOf(".rar")); } else { _FileName = xmlNodeList[i].InnerXml; } //排除TXT文本文件 if (!_FileName.EndsWith(".txt")) { //校验启动文件MD5 string _FileMd5 = Lib.FileHelper.GetMD5ByMD5CryptoService(AppDir + _FileName); if (_FileMd5 != xmlNodeList[i].Attributes["Md5"].Value) { string _FilePath = ""; if (APPVersion == "" || String.IsNullOrEmpty(APPVersion)) { _FilePath = DownPath + xmlNodeList[i].InnerXml; } else { _FilePath = DownPath + "\\" + APPVersion + xmlNodeList[i].InnerXml; } //校验相应版本备份文件MD5 _FileMd5 = Lib.FileHelper.GetMD5ByMD5CryptoService(_FilePath); if (_FileMd5 == xmlNodeList[i].Attributes["Md5"].Value) { //备份文件还原 File.Copy(_FilePath, AppDir + _FileName, true); } else { //启动文件校验还原失败 return false; } } } } //启动文件校验还原成功 return true; } /// /// 程序更新文件校验 /// /// 文件列表 /// 主程序版本号 /// 程序更新时间 /// 返回更新结果 private bool StartCheckUpdate(Dictionary FileList, string APPVersion) { string[] _Files = Directory.GetFiles(DownPath + "\\" + APPVersion); for (int i = 0; i < FileList.Count; i++) { decimal _Progress = (decimal)(i + 1) / FileList.Count * 100; MessageBeginInvoke("正在校验更新文件完整性......(" + _Progress.ToString("F0") + "%)", "lblMsg", "Label"); MessageBeginInvoke(_Progress.ToString("F2"), "downProgress", "ProgressBar"); string _FileMd5 = Lib.FileHelper.GetMD5ByMD5CryptoService(DownPath + "\\" + APPVersion + FileList.Keys.ElementAt(i)); if (_FileMd5 != FileList[FileList.Keys.ElementAt(i)]) { return false; } } return true; } /// /// 下载更新文件 /// /// 更新文件列表 /// 程序版本 /// 更新日期 private void StartDownLoad(XmlDocument XMLDoc, string APPVersion, string UpdateDate) { bool _FinishFalg = true; Dictionary _FileList = new Dictionary(); XmlNodeList xmlNodeList = XMLDoc.SelectNodes("//UpdateFileList//UpdateFile"); for (int i = 0; i < xmlNodeList.Count; i++) { _FileList.Add(xmlNodeList[i].InnerXml, xmlNodeList[i].Attributes["Md5"].Value); } int _DownEndCount = 0; if (!String.IsNullOrEmpty(APPVersion)) { //创建版本目录 if (!Directory.Exists(DownPath + "\\" + APPVersion)) { Directory.CreateDirectory(DownPath + "\\" + APPVersion); } else { //清空已下载同版本文件 Lib.FileHelper.DeleteDir(DownPath + "\\" + APPVersion); System.Threading.Thread.Sleep(300); } } FileCount = _FileList.Count; //创建更新文件下载进程 for (int i = 0; i < _FileList.Count; i++) { WebClient webClient = new WebClient(); string _FileName = _FileList.Keys.ElementAt(i); ProgressList.Add(_FileName, 0); webClient.DownloadProgressChanged += delegate (object _sender, DownloadProgressChangedEventArgs Event) { //显示下载进度 MessageBeginInvoke("正在下载更新:" + _FileName.Substring(_FileName.LastIndexOf("\\") + 1, _FileName.LastIndexOf(".rar") - 1).Replace("_", "__") + "(" + Lib.FileHelper.ConvertSize(Event.BytesReceived) + "/" + Lib.FileHelper.ConvertSize(Event.TotalBytesToReceive) + ")", "lblMsg", "Label"); ProgressList[_FileName] = Event.ProgressPercentage; //MessageBeginInvoke(Event.ProgressPercentage.ToString(), "downProgress", "ProgressBar"); }; webClient.DownloadFileCompleted += delegate (object _sender, AsyncCompletedEventArgs Event) { if (Event.Error != null) { _FinishFalg = false; } _DownEndCount += 1; if (_DownEndCount >= xmlNodeList.Count) { MessageBeginInvoke("更新文件下载完成", "lblMsg", "Label"); MessageBeginInvoke("正在校验更新文件完整性......", "lblMsg", "Label"); if (StartCheckUpdate(_FileList, APPVersion)) { MessageBeginInvoke("正在安装更新程序......", "lblMsg", "Label"); StartKillAPP(XMLDoc); if (Lib.FileHelper.CopyOldFilesToNewFiles(DownPath + "\\" + APPVersion, AppDir)) { try { Lib.ConfigHelper.UpdateAppConfig(XMLPath, "UpDate", UpdateDate); Lib.ConfigHelper.UpdateAppConfig(XMLPath, "SoftVersion", APPVersion); } catch { } EndUpdate("系统更新成功,正在启动收银系统......"); } else { EndUpdate("本次更新失败,将在下次启动时重试......"); } } else { EndUpdate("本次更新失败,将在下次启动时重试......"); } } }; string _FileUri = "http://" + UpdateUrl + ":" + UpdatePort + "/UpdateServer" + (XMLDoc.SelectNodes("//UpdateInfo//Version") == null ? "" : "/" + APPVersion) + "/UpdateFiles" + _FileName.Replace('\\', '/'); string _SaveFileName = DownPath + (APPVersion == null ? "" : "\\" + APPVersion) + _FileName; //创建文件下载线程 webClient.DownloadFileAsync(new Uri(_FileUri), _SaveFileName); System.Threading.Thread.Sleep(200); } //保存更新列表文件 XMLDoc.Save(DownPath + "\\UpdateList-" + APPVersion + ".xml"); } /// /// 更新完成启动程序 /// /// 更新结果消息 private void EndUpdate(string Msg) { MessageBeginInvoke(Msg, "lblMsg", "Label"); StartSetupAPP(Msg); System.Threading.Thread.Sleep(500); Environment.Exit(0); } #region 控件操作委托 /// /// 控件线程委托 /// /// 消息内容 /// 控件名称 /// 控件类型 delegate void DelegateMessage(string Msg, string ControlName, string ControlType); /// /// 线程委托操作事件 /// /// 消息内容 /// 控件名称 /// 控件类型 private void MessageBeginInvoke(string Msg, string ControlName, string ControlType) { Dispatcher.BeginInvoke(new DelegateMessage(MessageHandle), new object[] { Msg, ControlName, ControlType }); } /// /// 线程消息操作 /// /// 消息内容 /// 控件名称 /// 控件类型 private void MessageHandle(string Msg, string ControlName, string ControlsType) { switch (ControlsType) { case "ProgressBar": if (double.TryParse(Msg, out double _Value)) { ProgressBar _ProgressBar = (ProgressBar)FindName(ControlName); _ProgressBar.Value = _Value; } break; case "Label": Label _Label = (Label)FindName(ControlName); _Label.Content = Msg; break; case "Image": Image _Image = (Image)FindName(ControlName); _Image.Source = new BitmapImage(new Uri(Msg, UriKind.Relative)); break; } } #endregion } }