using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing.Design; using System.IO; using System.IO.Compression; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.UI.Design.WebControls; using System.Windows.Forms; namespace updater { public partial class Form1 : BaseWinForm { private UpgradeInfo localVersion; private UpgradeInfo upgradeInfo; private OfficeStarter appStarter = new OfficeStarter(); private static readonly string ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; private static readonly string LocalVersionFilePath = ApplicationBase + Path.GetFileName("version.json"); public static readonly string CONFIG_FILE = AppDomain.CurrentDomain.BaseDirectory + "app.json"; private static readonly string UpgradeDir = ApplicationBase + "update\\"; /* * gm-plugin.zverse.group 测试-开发 * pre-gm-plugin.gachafun.com 预发布 * gm-plugin.gachafun.com 正式发布 */ #if DEBUG private static string UpgradeInfoURI = "https://gm-plugin.gachafun.com/"; #else private static string UpgradeInfoURI = "https://gm-plugin.gachafun.com/"; #endif private string updateSource; private void InitAppByConfig() { try { if (File.Exists(CONFIG_FILE)) { string content = File.ReadAllText(CONFIG_FILE); if (content == null || content.Length == 0) return; AppConfig config = JsonConvert.DeserializeObject(content); // 插件网址 if (!string.IsNullOrEmpty(config.AppUrl)) { UpgradeInfoURI = config.AppUrl; } } } catch (Exception) { } } public Form1() { InitAppByConfig(); InitializeComponent(); string verTextFile = ApplicationBase + Path.GetFileName("app_version.txt"); string appVersion = File.Exists(verTextFile) ? File.ReadAllText(verTextFile) : null; if (appVersion != null && appVersion.Length > 0) { this.localVersion = new UpgradeInfo() { Version = appVersion }; } else { // 读取本地版本信息 string source = File.Exists(LocalVersionFilePath) ? File.ReadAllText(LocalVersionFilePath) : null; if (source != null && source.Length > 0) { UpgradeModel local = JsonConvert.DeserializeObject(source); this.localVersion = local.Info; } } } private void StartUpgrade() { string runningApp = CheckHostAppRunning(); if (!string.IsNullOrEmpty(runningApp)) { var result = MessageBox.Show(string.Format("检测到{0}正在运行中,是否强制关闭并继续执行更新操作", runningApp), "提示", MessageBoxButtons.OKCancel); if (result != DialogResult.OK) { ButtonProcess.Visible = true; ButtonProcess.Text = "继续更新"; return; } try { OfficeKiller.KillWPSProcess(); OfficeKiller.KillWordProcess(); } catch (Exception) { MessageBox.Show("强制关闭失败,请手动关闭后重新执行更新操作"); ButtonProcess.Visible = true; ButtonProcess.Text = "继续更新"; return; } } ButtonProcess.Visible = false; progressBar1.Visible = true; if (!Directory.Exists(UpgradeDir)) { Directory.CreateDirectory(UpgradeDir); } string updateFileName = UpgradeDir + Path.GetFileName(upgradeInfo.DownloadUrl); // 判断是否已经存在升级包 if (File.Exists(updateFileName)) { ExtractUpdatePackage(); return; } DownLoadFile(upgradeInfo.DownloadUrl, updateFileName); } public string CheckHostAppRunning() { Process[] array = Process.GetProcesses(); var hasWPS = false; var hasWord = false; foreach (Process item2 in array) { if (item2.ProcessName.Equals("WINWORD")) { hasWord = true; } else if (item2.ProcessName.Equals("wps")) { hasWPS = true; } } if (hasWord && hasWPS) return "WPS与Word"; if (hasWord) return "Word"; if (hasWPS) return "WPS"; return null; } private void LabelLog_Click(object sender, System.EventArgs e) { } public void CheckUpdate() { try { ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(UpgradeInfoURI + "api/v1/common/download/version"); httpWebRequest.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; HttpWebResponse resp = (HttpWebResponse)httpWebRequest.GetResponse(); // 获取响应内容 if (resp.StatusCode == HttpStatusCode.OK) { Stream receiveStream = resp.GetResponseStream(); StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); updateSource = readStream.ReadToEnd(); if (updateSource == null && updateSource.Length == 0) { LabelLog.Text = "获取更新信息失败,请稍后重试"; return; } resp.Close(); UpgradeModel update = JsonConvert.DeserializeObject(updateSource); ProcessUpdate(update); return; } } catch (Exception) { } LabelLog.Text = "获取更新信息失败,请稍后重试"; } private void ProcessUpdate(UpgradeModel update) { this.upgradeInfo = update.Info; LabelLog.Text = update.Info.Message; if (localVersion == null || update.Info.NeedUpgrade(localVersion.Version)) { //StartUpgrade(); ButtonProcess.Text = "立即更新"; ButtonProcess.Visible = true; } else { LabelLog.Text = "当前已是最新版本 V" + localVersion.Version; ButtonProcess.Text = "关闭"; ButtonProcess.Visible = true; } } private void Form1_Load(object sender, EventArgs e) { Task t = new Task(() => { ButtonProcess.Invoke(new Action(() => { CheckUpdate(); })); }); t.Start(); } public void DownLoadFile(string url, string filename) { try { WebClient client = new WebClient(); Uri uri = new Uri(url); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback); client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback); client.DownloadFileAsync(uri, filename); } catch (Exception e) { ButtonProcess.Visible = true; ButtonProcess.Text = "重新更新"; MessageBox.Show(e.Message); } } private void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e) { this.BeginInvoke(new Action(() => { progressBar1.Value = e.ProgressPercentage; })); } private void DownloadFileCallback(object sender, AsyncCompletedEventArgs e) { this.BeginInvoke(new Action(() => { ExtractUpdatePackage(); })); } private void StartInstallExe(string fileName) { // 启动更新程序 Process.Start(fileName); this.Close(); } private void ExtractUpdatePackage() { progressBar1.Value = 100; // 获取升级包路径 string updateFileName = UpgradeDir + Path.GetFileName(upgradeInfo.DownloadUrl); try { if (updateFileName.EndsWith(".exe")) { StartInstallExe(updateFileName); return; } // 可以考虑备份旧文件 //string destinationFolder = Path.Combine(applicationBase, "update\\old"); //CopyDirectory(applicationBase, destinationFolder); //ZipFile.ExtractToDirectory(zipFilePath, applicationBase); using (ZipArchive zip = ZipFile.OpenRead(updateFileName)) { foreach (ZipArchiveEntry entry in zip.Entries) { // 采用覆盖模式进行解压 try { entry.ExtractToFile(Path.Combine(ApplicationBase, entry.FullName), true); } catch (Exception) { } } } MessageBox.Show("更新完成, 您可以打开文档继续校对"); // 保存最新版本日志 try { File.WriteAllText(LocalVersionFilePath, updateSource); } catch (Exception) { } appStarter.StartWPS(); appStarter.StartMSOffice(); this.Close(); } catch (Exception) { try { File.Delete(updateFileName); }catch { } var ret = MessageBox.Show("升级失败,是否需要手动执行更新?", "更新失败", MessageBoxButtons.YesNo); if (ret == DialogResult.Yes) { Process.Start(upgradeInfo.DownloadUrl); this.Close(); } else { ButtonProcess.Visible = true; ButtonProcess.Text = "重新更新"; } } } public static void CopyDirectory(string sourceFolder, string destinationFolder) { Directory.CreateDirectory(destinationFolder); string moduleName = Process.GetCurrentProcess().MainModule.ModuleName; FileSystemInfo[] fileSystemInfos = new DirectoryInfo(sourceFolder).GetFileSystemInfos(); foreach (FileSystemInfo fileSystemInfo in fileSystemInfos) { if (fileSystemInfo is DirectoryInfo) { if (fileSystemInfo.Name != "update" && fileSystemInfo.Name != "logs") { if (!Directory.Exists(destinationFolder + "\\" + fileSystemInfo.Name)) { Directory.CreateDirectory(destinationFolder + "\\" + fileSystemInfo.Name); } CopyDirectory(fileSystemInfo.FullName, destinationFolder + "\\" + fileSystemInfo.Name); } } else if (!fileSystemInfo.FullName.EndsWith(moduleName)) { File.Copy(fileSystemInfo.FullName, destinationFolder + "\\" + fileSystemInfo.Name, overwrite: true); } } } private void BtnCancel_Click(object sender, EventArgs e) { this.Close(); Application.Exit(); } private void ButtonProcess_Click(object sender, EventArgs e) { switch (ButtonProcess.Text) { case "重新更新": case "立即更新": case "继续更新": StartUpgrade(); break; case "关闭": this.Close(); break; } } private void IconClose_Click(object sender, EventArgs e) { this.Close(); Application.Exit(); } private void panel1_MouseDown(object sender, MouseEventArgs e) { HandleMouseDownAndMove(); } } }