From 043a86103005105b7e0272c9d85dd78bf98fbdba Mon Sep 17 00:00:00 2001 From: HolographicHat Date: Sun, 2 Oct 2022 13:19:54 +0800 Subject: [PATCH] improve update --- YaeAchievement.csproj | 4 +++ res/App.Designer.cs | 21 +++++++------- res/App.resx | 7 +++-- res/App.zh.resx | 3 -- res/Updater.exe | Bin 0 -> 6144 bytes src/Export.cs | 6 ++-- src/Utils.cs | 65 +++++++++++++++++++++++------------------- 7 files changed, 57 insertions(+), 49 deletions(-) create mode 100644 res/Updater.exe diff --git a/YaeAchievement.csproj b/YaeAchievement.csproj index 4a61f4c..cf102bd 100644 --- a/YaeAchievement.csproj +++ b/YaeAchievement.csproj @@ -30,6 +30,10 @@ ResXFileCodeGenerator App.Designer.cs + + + PreserveNewest + diff --git a/res/App.Designer.cs b/res/App.Designer.cs index 3822fbf..b5000ca 100644 --- a/res/App.Designer.cs +++ b/res/App.Designer.cs @@ -18,7 +18,7 @@ namespace YaeAchievement.res { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class App { @@ -301,15 +301,6 @@ namespace YaeAchievement.res { } } - /// - /// Looks up a localized string similar to Unzip the package to update application.. - /// - internal static string UpdateDownloadFinish { - get { - return ResourceManager.GetString("UpdateDownloadFinish", resourceCulture); - } - } - /// /// Looks up a localized string similar to Downloading update package.... /// @@ -328,6 +319,16 @@ namespace YaeAchievement.res { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Updater { + get { + object obj = ResourceManager.GetObject("Updater", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized string similar to Upload error to appcenter.... /// diff --git a/res/App.resx b/res/App.resx index e8f2e59..731dd16 100644 --- a/res/App.resx +++ b/res/App.resx @@ -101,9 +101,6 @@ Input a number (0-5): Downloading update package... - - Unzip the package to update application. - YaeAchievement ({0}) @@ -125,4 +122,8 @@ Input a number (0-5): Network error ({0}: {1}) + + + Updater.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/res/App.zh.resx b/res/App.zh.resx index dff31f0..1cf073c 100644 --- a/res/App.zh.resx +++ b/res/App.zh.resx @@ -95,9 +95,6 @@ 正在下载更新包... - - 关闭程序后, 将压缩包解压至当前目录即可完成更新. - YaeAchievement - 原神成就导出工具 ({0}) diff --git a/res/Updater.exe b/res/Updater.exe new file mode 100644 index 0000000000000000000000000000000000000000..ea97c8af148238b73ab2298c5d19f2f5810a6b10 GIT binary patch literal 6144 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 Dwddgh literal 0 HcmV?d00001 diff --git a/src/Export.cs b/src/Export.cs index 4eb9053..6f7442f 100644 --- a/src/Export.cs +++ b/src/Export.cs @@ -44,7 +44,7 @@ public static class Export { RequestUri = new Uri($"https://77.cocogoat.work/v1/memo?source={App.AllAchievement}"), Content = new StringContent(result, Encoding.UTF8, "application/json") }; - using var response = Utils.CHttpClient.Value.Send(request); + using var response = Utils.CHttpClient.Send(request); if (response.StatusCode != HttpStatusCode.Created) { Console.WriteLine(App.ExportToCocogoatFail); return; @@ -60,14 +60,14 @@ public static class Export { var id = Guid.NewGuid().ToString("N").Substring(20, 8); var result = JsonSerializer.Serialize(new Dictionary { { "key", id }, - { "data", data.List.Where(a => a.Status is Status.Finished or Status.RewardTaken) } + { "data", ExportToUIAFApp(data) } }); using var request = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri("https://api.qyinter.com/achievementRedis"), Content = new StringContent(result, Encoding.UTF8, "application/json") }; - using var response = Utils.CHttpClient.Value.Send(request); + using var response = Utils.CHttpClient.Send(request); Console.WriteLine(App.ExportToWxApp1Success, id); } diff --git a/src/Utils.cs b/src/Utils.cs index e48b6d7..4873b89 100644 --- a/src/Utils.cs +++ b/src/Utils.cs @@ -14,19 +14,16 @@ namespace YaeAchievement; public static class Utils { - public static readonly Lazy CHttpClient = new (() => { - var c = new HttpClient(new HttpClientHandler { - Proxy = GlobalVars.DebugProxy ? new WebProxy("http://127.0.0.1:8888") : null, - AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip - }) { - DefaultRequestHeaders = { - UserAgent = { - new ProductInfoHeaderValue("YaeAchievement", GlobalVars.AppVersion.ToString(2)) - } + public static readonly HttpClient CHttpClient = new (new HttpClientHandler { + Proxy = GlobalVars.DebugProxy ? new WebProxy("http://127.0.0.1:8888") : null, + AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip + }) { + DefaultRequestHeaders = { + UserAgent = { + new ProductInfoHeaderValue("YaeAchievement", GlobalVars.AppVersion.ToString(2)) } - }; - return c; - }); + } + }; public static byte[] GetBucketFileAsByteArray(string path, bool cache = true) { try { @@ -38,7 +35,7 @@ public static class Utils { if (cache && cacheFile.Exists()) { msg.Headers.TryAddWithoutValidation("If-None-Match", $"{cacheFile.Read().Etag}"); } - using var response = CHttpClient.Value.Send(msg); + using var response = CHttpClient.Send(msg); if (cache && response.StatusCode == HttpStatusCode.NotModified) { return cacheFile.Read().Content.ToByteArray(); } @@ -90,10 +87,16 @@ public static class Utils { Console.WriteLine(App.UpdateDescription, info.Description); if (info.EnableAutoDownload) { Console.WriteLine(App.UpdateDownloading); - var fullPath = Path.GetFullPath($"update.{Path.GetExtension(info.PackageLink)}"); - File.WriteAllBytes(fullPath, GetBucketFileAsByteArray(info.PackageLink)); - Console.WriteLine(App.UpdateDownloadFinish); - ShellOpen(fullPath); + var tmpPath = Path.GetTempFileName(); + File.WriteAllBytes(tmpPath, GetBucketFileAsByteArray(info.PackageLink)); + var updaterArgs = $"{Environment.ProcessId}|{Environment.ProcessPath}|{tmpPath}"; + var updaterPath = Path.Combine(GlobalVars.DataPath, "update.exe"); + var updaterHash = App.Updater.MD5Hash(); + if (!File.Exists(updaterPath) || File.ReadAllBytes(updaterPath).MD5Hash() != updaterHash) { + File.WriteAllBytes(updaterPath, App.Updater); + } + ShellOpen(updaterPath, updaterArgs.ToBytes().ToBase64()); + GlobalVars.PauseOnExit = false; Environment.Exit(0); } Console.WriteLine(App.DownloadLink, info.PackageLink); @@ -109,7 +112,6 @@ public static class Utils { } } - public static void CheckSelfIsRunning() { Process.EnterDebugMode(); var cur = Process.GetCurrentProcess(); @@ -123,13 +125,17 @@ public static class Utils { } // ReSharper disable once UnusedMethodReturnValue.Global - public static bool ShellOpen(string path) { + public static bool ShellOpen(string path, string? args = null) { try { + var startInfo = new ProcessStartInfo { + FileName = path, + UseShellExecute = true + }; + if (args != null) { + startInfo.Arguments = args; + } return new Process { - StartInfo = { - FileName = path, - UseShellExecute = true - } + StartInfo = startInfo }.Start(); } catch (Exception) { return false; @@ -162,8 +168,10 @@ public static class Utils { public static void InstallExitHook() { AppDomain.CurrentDomain.ProcessExit += (_, _) => { proc?.Kill(); - Console.WriteLine(App.PressKeyToExit); - Console.ReadKey(); + if (GlobalVars.PauseOnExit) { + Console.WriteLine(App.PressKeyToExit); + Console.ReadKey(); + } }; } @@ -258,11 +266,8 @@ public static class Utils { if (!installed) { Console.WriteLine(App.VcRuntimeDownload); var pkgPath = Path.Combine(GlobalVars.DataPath, "vc_redist.x64.exe"); - var stream = await CHttpClient.Value.GetStreamAsync("https://aka.ms/vs/17/release/vc_redist.x64.exe"); - var output = File.OpenWrite(pkgPath); - await stream.CopyToAsync(output); - stream.Close(); - output.Close(); + var bytes = await CHttpClient.GetByteArrayAsync("https://aka.ms/vs/17/release/vc_redist.x64.exe"); + await File.WriteAllBytesAsync(pkgPath, bytes); Console.WriteLine(App.VcRuntimeInstalling); using var process = new Process { StartInfo = {