378 lines
13 KiB
C#

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 正式发布
*/
private static string UpgradeInfoURI = "https://gm-plugin-fn.gachafun.com/";
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<AppConfig>(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<UpgradeModel>(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<UpgradeModel>(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();
}
}
}