diff --git a/ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs b/ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs index 78e3758..c5a59de 100644 --- a/ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs +++ b/ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs @@ -3,7 +3,6 @@ using ContextMenuManager; using System; using System.Drawing; using System.IO; -using System.Net; using System.Windows.Forms; namespace BluePointLilac.Controls @@ -20,9 +19,7 @@ namespace BluePointLilac.Controls { frm.Url = this.Url; frm.FilePath = this.FilePath; - bool flag = frm.ShowDialog() == DialogResult.OK; - if(!flag) File.Delete(FilePath); - return flag; + return frm.ShowDialog() == DialogResult.OK; } } @@ -30,21 +27,22 @@ namespace BluePointLilac.Controls { public DownloadForm() { - this.MinimizeBox = this.MaximizeBox = false; + this.Text = AppString.General.AppName; this.FormBorderStyle = FormBorderStyle.FixedSingle; this.StartPosition = FormStartPosition.CenterParent; + this.MinimizeBox = this.MaximizeBox = this.ShowInTaskbar = false; this.Font = new Font(SystemFonts.MessageBoxFont.FontFamily, 9F); this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); this.Controls.AddRange(new Control[] { pgbDownload, btnCancel }); - pgbDownload.Left = pgbDownload.Top = btnCancel.Top = 20.DpiZoom(); - pgbDownload.Height = btnCancel.Height; - pgbDownload.Width = 200.DpiZoom(); - btnCancel.Left = pgbDownload.Right + 20.DpiZoom(); - this.ClientSize = new Size(btnCancel.Right + 20.DpiZoom(), btnCancel.Bottom + 20.DpiZoom()); this.Load += (sender, e) => DownloadFile(Url, FilePath); + this.InitializeComponents(); } - readonly ProgressBar pgbDownload = new ProgressBar(); + readonly ProgressBar pgbDownload = new ProgressBar + { + Width = 200.DpiZoom(), + Maximum = 100 + }; readonly Button btnCancel = new Button { DialogResult = DialogResult.Cancel, @@ -55,33 +53,37 @@ namespace BluePointLilac.Controls public string Url { get; set; } public string FilePath { get; set; } + private void InitializeComponents() + { + int a = 20.DpiZoom(); + pgbDownload.Left = pgbDownload.Top = btnCancel.Top = a; + pgbDownload.Height = btnCancel.Height; + btnCancel.Left = pgbDownload.Right + a; + this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a); + } + private void DownloadFile(string url, string filePath) { try { - this.Activate(); - using(WebResponse response = WebRequest.Create(url).GetResponse()) - using(Stream webStream = response.GetResponseStream()) - using(FileStream fileStream = new FileStream(filePath, FileMode.Create)) + using(UAWebClient client = new UAWebClient()) { - double fullSize = response.ContentLength; - pgbDownload.Maximum = (int)fullSize; - double downloadedSize = 0; - int incrementSize; - do + client.DownloadProgressChanged += (sender, e) => { - if(this.DialogResult == DialogResult.Cancel) return; - byte[] by = new byte[1024]; - incrementSize = webStream.Read(by, 0, by.Length); - downloadedSize += incrementSize; - fileStream.Write(by, 0, incrementSize); - pgbDownload.Value = (int)downloadedSize; - - double downloaded = Math.Round(downloadedSize / fullSize * 100, 2); - this.Text = $"Downloading: {downloaded}%"; - Application.DoEvents(); - } while(incrementSize > 0); - this.DialogResult = DialogResult.OK; + int value = e.ProgressPercentage; + this.Text = $"Downloading: {value}%"; + pgbDownload.Value = value; + if(this.DialogResult == DialogResult.Cancel) + { + client.CancelAsync(); + File.Delete(FilePath); + } + }; + client.DownloadFileCompleted += (sender, e) => + { + this.DialogResult = DialogResult.OK; + }; + client.DownloadFileAsync(new Uri(url), filePath); } } catch(Exception e) diff --git a/ContextMenuManager/BluePointLilac.Methods/UAWebClient.cs b/ContextMenuManager/BluePointLilac.Methods/UAWebClient.cs new file mode 100644 index 0000000..5b50745 --- /dev/null +++ b/ContextMenuManager/BluePointLilac.Methods/UAWebClient.cs @@ -0,0 +1,16 @@ +using System.Text; +using System.Net; + +namespace BluePointLilac.Methods +{ + /// 此类主要为了解决访问Github的一些问题 + public class UAWebClient : WebClient + { + public UAWebClient() + { + this.Encoding = Encoding.UTF8; + this.Headers.Add("User-Agent", "UserAgent");//远程服务器返回错误: (403) 已禁止 + ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;//TLS12, 请求被中止: 未能创建 SSL/TLS 安全通道 + } + } +} \ No newline at end of file diff --git a/ContextMenuManager/Updater.cs b/ContextMenuManager/Updater.cs index 3c769e6..25abdfe 100644 --- a/ContextMenuManager/Updater.cs +++ b/ContextMenuManager/Updater.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Net; using System.Runtime.Serialization.Json; using System.Text; using System.Windows.Forms; @@ -16,40 +15,64 @@ namespace ContextMenuManager { sealed class Updater { - const string GithubLatest = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/releases/latest"; - const string GiteeLatest = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/releases/latest"; - const string GithubLangs = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/languages"; - const string GiteeLangs = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/languages"; + const string GithubLatest = "https://github.com/BluePointLilac/ContextMenuManager/releases/latest"; + const string GithubLatestApi = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/releases/latest"; + const string GithubLangsApi = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/languages"; const string GithubTexts = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/ContextMenuManager/Properties/Resources/Texts"; - const string GiteeTexts = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/Texts"; - const string GithubDonate = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/Donate.md"; - const string GiteeDonate = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/Donate.md"; + const string GithubDonateRaw = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/Donate.md"; + const string GithubDonate = "https://github.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md"; + const string GiteeReleases = "https://gitee.com/BluePointLilac/ContextMenuManager/releases"; + const string GiteeLatestApi = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/releases/latest"; + const string GiteeLangsApi = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/languages"; + const string GiteeTexts = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/Texts"; + const string GiteeDonateRaw = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/Donate.md"; + const string GiteeDonate = "https://gitee.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md"; + + /// 定期检查更新 public static void PeriodicUpdate() { int day = AppConfig.UpdateFrequency; if(day == -1) return;//自动检测更新频率为-1则从不自动检查更新 - //如果上次检测更新时间加上时间间隔早于今天以前就进行更新操作 - if(AppConfig.LastCheckUpdateTime.AddDays(day) < DateTime.Today) Update(); + //如果上次检测更新时间加上时间间隔早于或等于今天以前就进行更新操作 + if(AppConfig.LastCheckUpdateTime.AddDays(day) <= DateTime.Today) Update(false); } - public static bool Update() + /// 更新程序以及程序字典 + /// 是否为手动点击更新 + public static void Update(bool isManual) { AppConfig.LastCheckUpdateTime = DateTime.Today; - UpdateText(); - return UpdateApp(); + UpdateText(isManual); + UpdateApp(isManual); } - private static bool UpdateApp() + /// 更新程序 + /// 是否为手动点击更新 + private static void UpdateApp(bool isManual) { - string url = AppConfig.RequestUseGithub ? GithubLatest : GiteeLatest; + string url = AppConfig.RequestUseGithub ? GithubLatestApi : GiteeLatestApi; XmlDocument doc = GetWebJsonToXml(url); - if(doc == null) return false; + if(doc == null) + { + if(isManual) + { + MessageBoxEx.Show(AppString.Message.FailedToReadNetworkFile); + url = AppConfig.RequestUseGithub ? GithubLatest : GiteeReleases; + ExternalProgram.OpenUrl(url); + } + return; + } XmlNode root = doc.FirstChild; XmlElement tagNameXE = (XmlElement)root.SelectSingleNode("tag_name"); Version webVer = new Version(tagNameXE.InnerText); Version appVer = new Version(Application.ProductVersion); - if(webVer > appVer) + //appVer = new Version(0, 0, 0, 0);//测试用 + if(appVer >= webVer) + { + if(isManual) MessageBoxEx.Show(AppString.Message.VersionIsLatest); + } + else { XmlElement bodyXE = (XmlElement)root.SelectSingleNode("body"); string info = AppString.Message.UpdateInfo.Replace("%v1", appVer.ToString()).Replace("%v2", webVer.ToString()); @@ -77,13 +100,14 @@ namespace ContextMenuManager } } } - return true; } - return false; } - private static void UpdateText() + /// 更新程序字典 + /// 是否为手动点击更新 + private static void UpdateText(bool isManual) { + bool flag = isManual; string url = AppConfig.RequestUseGithub ? GithubTexts : GiteeTexts; string[] fileNames = new[] { @@ -95,17 +119,24 @@ namespace ContextMenuManager string fileUrl = $"{url}/{fileName}"; string filePath = $@"{AppConfig.WebDicsDir}\{fileName}"; string contents = GetWebString(fileUrl); - if(string.IsNullOrEmpty(contents)) continue; + if(string.IsNullOrEmpty(contents)) { flag = false; continue; } contents = contents.Replace("\n", Environment.NewLine); File.WriteAllText(filePath, contents, Encoding.Unicode); } + if(!flag) MessageBoxEx.Show(AppString.Message.FailedToReadNetworkFile); } + /// 显示语言下载对话框 + /// 返回值为是否下载了语言文件 public static bool ShowLanguageDialog() { - string url = AppConfig.RequestUseGithub ? GithubLangs : GiteeLangs; + string url = AppConfig.RequestUseGithub ? GithubLangsApi : GiteeLangsApi; XmlDocument doc = GetWebJsonToXml(url); - if(doc == null) return false; + if(doc == null) + { + MessageBoxEx.Show(AppString.Message.FailedToReadNetworkFile); + return false; + } Dictionary langs = new Dictionary(); foreach(XmlElement itemXE in doc.FirstChild.SelectNodes("item")) { @@ -133,12 +164,18 @@ namespace ContextMenuManager return false; } + /// 显示捐赠名单对话框 public static void ShowDonateDialog() { - string url = AppConfig.RequestUseGithub ? GithubDonate : GiteeDonate; + string url = AppConfig.RequestUseGithub ? GithubDonateRaw : GiteeDonateRaw; string contents = GetWebString(url); - //string contents = File.ReadAllText(@"..\..\..\Donate.md");//用于求和更新Donate.md文件 - if(contents == null) ExternalProgram.OpenUrl(url); + //contents = File.ReadAllText(@"..\..\..\Donate.md");//用于求和更新Donate.md文件 + if(contents == null) + { + MessageBoxEx.Show(AppString.Message.FailedToReadNetworkFile); + url = AppConfig.RequestUseGithub ? GithubDonate : GiteeDonate; + ExternalProgram.OpenUrl(url); + } else { using(DonateListDialog dlg = new DonateListDialog()) @@ -149,6 +186,7 @@ namespace ContextMenuManager } } + /// 加工处理更新信息,去掉标题头 private static string MachinedInfo(string info) { string str = string.Empty; @@ -169,28 +207,33 @@ namespace ContextMenuManager return str; } + /// 获取网页文本 private static string GetWebString(string url) { try { - using(WebResponse response = WebRequest.Create(url).GetResponse()) - using(StreamReader stream = new StreamReader(response.GetResponseStream())) - return stream?.ReadToEnd(); + using(UAWebClient client = new UAWebClient()) + { + return client.DownloadString(url); + } } catch { return null; } } + /// 获取网页Json文本并加工为Xml private static XmlDocument GetWebJsonToXml(string url) { try { - using(WebResponse response = WebRequest.Create(url).GetResponse()) - using(StreamReader stream = new StreamReader(response.GetResponseStream())) - using(XmlReader reader = JsonReaderWriterFactory.CreateJsonReader(stream?.BaseStream, XmlDictionaryReaderQuotas.Max)) + using(UAWebClient client = new UAWebClient()) { - XmlDocument doc = new XmlDocument(); - doc.Load(reader); - return doc; + byte[] bytes = client.DownloadData(url); + using(XmlReader xReader = JsonReaderWriterFactory.CreateJsonReader(bytes, XmlDictionaryReaderQuotas.Max)) + { + XmlDocument doc = new XmlDocument(); + doc.Load(xReader); + return doc; + } } } catch { return null; }