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 0000000..ea97c8a
Binary files /dev/null and b/res/Updater.exe differ
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 = {