mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-13 09:58:13 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
204f211249 | ||
|
|
043a861030 | ||
|
|
09a9d4c22b | ||
|
|
9094b9c718 | ||
|
|
d7ac18587a |
@@ -30,6 +30,10 @@
|
|||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>App.Designer.cs</LastGenOutput>
|
<LastGenOutput>App.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<None Remove="res\Updater.exe" />
|
||||||
|
<EmbeddedResource Include="res\Updater.exe">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
<AdditionalDependencies>detours-x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>detours-x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy $(TargetPath) $(ProjectDir)..\bin\Debug\net6.0\win-x64</Command>
|
<Command>copy $(TargetPath) $(ProjectDir)..\bin\Debug\net6.0\win-x64\YaeAchievementLib.dll /y</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ namespace Hook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Run(HMODULE* phModule) {
|
void Run(HMODULE* phModule) {
|
||||||
AllocConsole();
|
//AllocConsole();
|
||||||
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
|
//freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
|
||||||
while (
|
while (
|
||||||
GetModuleHandle("UserAssembly.dll") == nullptr ||
|
GetModuleHandle("UserAssembly.dll") == nullptr ||
|
||||||
(unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == 0
|
(unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == 0
|
||||||
|
|||||||
21
res/App.Designer.cs
generated
21
res/App.Designer.cs
generated
@@ -18,7 +18,7 @@ namespace YaeAchievement.res {
|
|||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// 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.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
internal class App {
|
internal class App {
|
||||||
@@ -301,15 +301,6 @@ namespace YaeAchievement.res {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Unzip the package to update application..
|
|
||||||
/// </summary>
|
|
||||||
internal static string UpdateDownloadFinish {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("UpdateDownloadFinish", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Downloading update package....
|
/// Looks up a localized string similar to Downloading update package....
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -328,6 +319,16 @@ namespace YaeAchievement.res {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Byte[].
|
||||||
|
/// </summary>
|
||||||
|
internal static byte[] Updater {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("Updater", resourceCulture);
|
||||||
|
return ((byte[])(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Upload error to appcenter....
|
/// Looks up a localized string similar to Upload error to appcenter....
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -101,9 +101,6 @@ Input a number (0-5): </value>
|
|||||||
<data name="UpdateDownloading" xml:space="preserve">
|
<data name="UpdateDownloading" xml:space="preserve">
|
||||||
<value>Downloading update package...</value>
|
<value>Downloading update package...</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="UpdateDownloadFinish" xml:space="preserve">
|
|
||||||
<value>Unzip the package to update application.</value>
|
|
||||||
</data>
|
|
||||||
<data name="AppBanner" xml:space="preserve">
|
<data name="AppBanner" xml:space="preserve">
|
||||||
<value>YaeAchievement ({0})</value>
|
<value>YaeAchievement ({0})</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -125,4 +122,8 @@ Input a number (0-5): </value>
|
|||||||
<data name="ExceptionNetwork" xml:space="preserve">
|
<data name="ExceptionNetwork" xml:space="preserve">
|
||||||
<value>Network error ({0}: {1})</value>
|
<value>Network error ({0}: {1})</value>
|
||||||
</data>
|
</data>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="Updater" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>Updater.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -35,10 +35,10 @@
|
|||||||
<value>在小程序导入页面输入以下代码: {0}</value>
|
<value>在小程序导入页面输入以下代码: {0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ExportToSnapGenshinSuccess" xml:space="preserve">
|
<data name="ExportToSnapGenshinSuccess" xml:space="preserve">
|
||||||
<value>在 SnapGenshin 进行下一步操作</value>
|
<value>在 SnapHutao 进行下一步操作</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ExportToSnapGenshinNeedUpdate" xml:space="preserve">
|
<data name="ExportToSnapGenshinNeedUpdate" xml:space="preserve">
|
||||||
<value>更新 SnapGenshin 至最新版本后重试</value>
|
<value>更新 SnapHutao 至最新版本后重试</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ExportToFileSuccess" xml:space="preserve">
|
<data name="ExportToFileSuccess" xml:space="preserve">
|
||||||
<value>成就数据已导出至 {0}</value>
|
<value>成就数据已导出至 {0}</value>
|
||||||
@@ -95,9 +95,6 @@
|
|||||||
<data name="UpdateDownloading" xml:space="preserve">
|
<data name="UpdateDownloading" xml:space="preserve">
|
||||||
<value>正在下载更新包...</value>
|
<value>正在下载更新包...</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="UpdateDownloadFinish" xml:space="preserve">
|
|
||||||
<value>关闭程序后, 将压缩包解压至当前目录即可完成更新.</value>
|
|
||||||
</data>
|
|
||||||
<data name="AppBanner" xml:space="preserve">
|
<data name="AppBanner" xml:space="preserve">
|
||||||
<value>YaeAchievement - 原神成就导出工具 ({0})</value>
|
<value>YaeAchievement - 原神成就导出工具 ({0})</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
BIN
res/Updater.exe
Normal file
BIN
res/Updater.exe
Normal file
Binary file not shown.
@@ -46,7 +46,10 @@ public static class AppConfig {
|
|||||||
if (!File.Exists(path)) {
|
if (!File.Exists(path)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var content = File.ReadAllText(path);
|
var copiedLogFilePath = Path.GetTempFileName();
|
||||||
|
File.Copy(path, copiedLogFilePath, true);
|
||||||
|
var content = File.ReadAllText(copiedLogFilePath);
|
||||||
|
File.Delete(copiedLogFilePath);
|
||||||
var matchResult = Regex.Match(content, @"(?m).:/.+(GenshinImpact_Data|YuanShen_Data)");
|
var matchResult = Regex.Match(content, @"(?m).:/.+(GenshinImpact_Data|YuanShen_Data)");
|
||||||
if (!matchResult.Success) {
|
if (!matchResult.Success) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ public class CacheFile {
|
|||||||
public DateTime LastWriteTime => Exists() ? File.GetLastWriteTimeUtc(_cacheName) : DateTime.UnixEpoch;
|
public DateTime LastWriteTime => Exists() ? File.GetLastWriteTimeUtc(_cacheName) : DateTime.UnixEpoch;
|
||||||
|
|
||||||
public CacheFile(string identifier) {
|
public CacheFile(string identifier) {
|
||||||
Directory.CreateDirectory(Path.Combine(GlobalVars.AppPath, "cache"));
|
_cacheName = Path.Combine(GlobalVars.CachePath, $"{identifier.MD5Hash()[..16]}.miko");
|
||||||
_cacheName = Path.Combine(GlobalVars.AppPath, $"cache/{identifier.MD5Hash()[..16]}.miko");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists() => File.Exists(_cacheName);
|
public bool Exists() => File.Exists(_cacheName);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public static class Export {
|
|||||||
RequestUri = new Uri($"https://77.cocogoat.work/v1/memo?source={App.AllAchievement}"),
|
RequestUri = new Uri($"https://77.cocogoat.work/v1/memo?source={App.AllAchievement}"),
|
||||||
Content = new StringContent(result, Encoding.UTF8, "application/json")
|
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) {
|
if (response.StatusCode != HttpStatusCode.Created) {
|
||||||
Console.WriteLine(App.ExportToCocogoatFail);
|
Console.WriteLine(App.ExportToCocogoatFail);
|
||||||
return;
|
return;
|
||||||
@@ -67,7 +67,7 @@ public static class Export {
|
|||||||
RequestUri = new Uri("https://api.qyinter.com/achievementRedis"),
|
RequestUri = new Uri("https://api.qyinter.com/achievementRedis"),
|
||||||
Content = new StringContent(result, Encoding.UTF8, "application/json")
|
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);
|
Console.WriteLine(App.ExportToWxApp1Success, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,29 @@ namespace YaeAchievement;
|
|||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
// ReSharper disable ConvertToConstant.Global
|
// ReSharper disable ConvertToConstant.Global
|
||||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||||
|
// ReSharper disable once MemberCanBePrivate.Global
|
||||||
|
|
||||||
public static class GlobalVars {
|
public static class GlobalVars {
|
||||||
|
|
||||||
public static bool DebugProxy => false;
|
public static bool DebugProxy => false;
|
||||||
public static bool UnexpectedExit { get; set; } = true;
|
public static bool UnexpectedExit { get; set; } = true;
|
||||||
|
public static bool PauseOnExit { get; set; } = true;
|
||||||
public static Version AppVersion { get; } = Assembly.GetEntryAssembly()!.GetName().Version!;
|
public static Version AppVersion { get; } = Assembly.GetEntryAssembly()!.GetName().Version!;
|
||||||
|
|
||||||
private static readonly string DataDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
|
|
||||||
public static readonly string LibPath = Path.Combine(DataDir, "YaeAchievement.dll");
|
|
||||||
public static readonly string AppPath = AppDomain.CurrentDomain.BaseDirectory;
|
public static readonly string AppPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
private static readonly string CommonData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
|
||||||
|
public static readonly string DataPath = Path.Combine(CommonData, "Yae");
|
||||||
|
public static readonly string CachePath = Path.Combine(DataPath, "cache");
|
||||||
|
public static readonly string LibFilePath = Path.Combine(DataPath, "YaeAchievement.dll");
|
||||||
|
|
||||||
public const uint AppVersionCode = 30;
|
public const uint AppVersionCode = 31;
|
||||||
public const string AppVersionName = "2.2";
|
public const string AppVersionName = "2.2.1";
|
||||||
|
|
||||||
public const string PipeName = "YaeAchievementPipe";
|
public const string PipeName = "YaeAchievementPipe";
|
||||||
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";
|
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";
|
||||||
|
|
||||||
|
static GlobalVars() {
|
||||||
|
Directory.CreateDirectory(DataPath);
|
||||||
|
Directory.CreateDirectory(CachePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
src/Utils.cs
57
src/Utils.cs
@@ -14,8 +14,7 @@ namespace YaeAchievement;
|
|||||||
|
|
||||||
public static class Utils {
|
public static class Utils {
|
||||||
|
|
||||||
public static readonly Lazy<HttpClient> CHttpClient = new (() => {
|
public static readonly HttpClient CHttpClient = new (new HttpClientHandler {
|
||||||
var c = new HttpClient(new HttpClientHandler {
|
|
||||||
Proxy = GlobalVars.DebugProxy ? new WebProxy("http://127.0.0.1:8888") : null,
|
Proxy = GlobalVars.DebugProxy ? new WebProxy("http://127.0.0.1:8888") : null,
|
||||||
AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip
|
AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip
|
||||||
}) {
|
}) {
|
||||||
@@ -25,8 +24,6 @@ public static class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return c;
|
|
||||||
});
|
|
||||||
|
|
||||||
public static byte[] GetBucketFileAsByteArray(string path, bool cache = true) {
|
public static byte[] GetBucketFileAsByteArray(string path, bool cache = true) {
|
||||||
try {
|
try {
|
||||||
@@ -38,7 +35,7 @@ public static class Utils {
|
|||||||
if (cache && cacheFile.Exists()) {
|
if (cache && cacheFile.Exists()) {
|
||||||
msg.Headers.TryAddWithoutValidation("If-None-Match", $"{cacheFile.Read().Etag}");
|
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) {
|
if (cache && response.StatusCode == HttpStatusCode.NotModified) {
|
||||||
return cacheFile.Read().Content.ToByteArray();
|
return cacheFile.Read().Content.ToByteArray();
|
||||||
}
|
}
|
||||||
@@ -90,10 +87,16 @@ public static class Utils {
|
|||||||
Console.WriteLine(App.UpdateDescription, info.Description);
|
Console.WriteLine(App.UpdateDescription, info.Description);
|
||||||
if (info.EnableAutoDownload) {
|
if (info.EnableAutoDownload) {
|
||||||
Console.WriteLine(App.UpdateDownloading);
|
Console.WriteLine(App.UpdateDownloading);
|
||||||
var fullPath = Path.GetFullPath($"update.{Path.GetExtension(info.PackageLink)}");
|
var tmpPath = Path.GetTempFileName();
|
||||||
File.WriteAllBytes(fullPath, GetBucketFileAsByteArray(info.PackageLink));
|
File.WriteAllBytes(tmpPath, GetBucketFileAsByteArray(info.PackageLink));
|
||||||
Console.WriteLine(App.UpdateDownloadFinish);
|
var updaterArgs = $"{Environment.ProcessId}|{Environment.ProcessPath}|{tmpPath}";
|
||||||
ShellOpen(fullPath);
|
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);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
Console.WriteLine(App.DownloadLink, info.PackageLink);
|
Console.WriteLine(App.DownloadLink, info.PackageLink);
|
||||||
@@ -102,10 +105,10 @@ public static class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useLocalLib) {
|
if (useLocalLib) {
|
||||||
Console.WriteLine(@"Use local native lib.");
|
Console.WriteLine(@"[DEBUG] Use local native lib.");
|
||||||
File.Copy(Path.Combine(GlobalVars.AppPath, "YaeAchievementLib.dll"), GlobalVars.LibPath, true);
|
File.Copy(Path.Combine(GlobalVars.AppPath, "YaeAchievementLib.dll"), GlobalVars.LibFilePath, true);
|
||||||
} else if (info.EnableLibDownload) {
|
} else if (info.EnableLibDownload) {
|
||||||
File.WriteAllBytes(GlobalVars.LibPath, GetBucketFileAsByteArray("schicksal/lib.dll"));
|
File.WriteAllBytes(GlobalVars.LibFilePath, GetBucketFileAsByteArray("schicksal/lib.dll"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,13 +125,17 @@ public static class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable once UnusedMethodReturnValue.Global
|
// ReSharper disable once UnusedMethodReturnValue.Global
|
||||||
public static bool ShellOpen(string path) {
|
public static bool ShellOpen(string path, string? args = null) {
|
||||||
try {
|
try {
|
||||||
return new Process {
|
var startInfo = new ProcessStartInfo {
|
||||||
StartInfo = {
|
|
||||||
FileName = path,
|
FileName = path,
|
||||||
UseShellExecute = true
|
UseShellExecute = true
|
||||||
|
};
|
||||||
|
if (args != null) {
|
||||||
|
startInfo.Arguments = args;
|
||||||
}
|
}
|
||||||
|
return new Process {
|
||||||
|
StartInfo = startInfo
|
||||||
}.Start();
|
}.Start();
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
return false;
|
return false;
|
||||||
@@ -161,8 +168,10 @@ public static class Utils {
|
|||||||
public static void InstallExitHook() {
|
public static void InstallExitHook() {
|
||||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => {
|
AppDomain.CurrentDomain.ProcessExit += (_, _) => {
|
||||||
proc?.Kill();
|
proc?.Kill();
|
||||||
|
if (GlobalVars.PauseOnExit) {
|
||||||
Console.WriteLine(App.PressKeyToExit);
|
Console.WriteLine(App.PressKeyToExit);
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,13 +203,13 @@ public static class Utils {
|
|||||||
public static Thread StartAndWaitResult(string exePath, Func<string, bool> onReceive) {
|
public static Thread StartAndWaitResult(string exePath, Func<string, bool> onReceive) {
|
||||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => {
|
AppDomain.CurrentDomain.ProcessExit += (_, _) => {
|
||||||
try {
|
try {
|
||||||
File.Delete(GlobalVars.LibPath);
|
File.Delete(GlobalVars.LibFilePath);
|
||||||
} catch (Exception) { /* ignored */ }
|
} catch (Exception) { /* ignored */ }
|
||||||
};
|
};
|
||||||
if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) {
|
if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) {
|
||||||
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail"));
|
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail"));
|
||||||
}
|
}
|
||||||
if (Injector.LoadLibraryAndInject(hProcess, GlobalVars.LibPath) != 0) {
|
if (Injector.LoadLibraryAndInject(hProcess, GlobalVars.LibFilePath) != 0) {
|
||||||
if (!Native.TerminateProcess(hProcess, 0)) {
|
if (!Native.TerminateProcess(hProcess, 0)) {
|
||||||
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("TerminateProcess fail"));
|
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("TerminateProcess fail"));
|
||||||
}
|
}
|
||||||
@@ -256,17 +265,19 @@ public static class Utils {
|
|||||||
.Any(name => name.Contains("Microsoft Visual C++ 2022 X64 "));
|
.Any(name => name.Contains("Microsoft Visual C++ 2022 X64 "));
|
||||||
if (!installed) {
|
if (!installed) {
|
||||||
Console.WriteLine(App.VcRuntimeDownload);
|
Console.WriteLine(App.VcRuntimeDownload);
|
||||||
var pkgPath = Path.Combine(GlobalVars.AppPath, "vc_redist.x64.exe");
|
var pkgPath = Path.Combine(GlobalVars.DataPath, "vc_redist.x64.exe");
|
||||||
await using var stream = await CHttpClient.Value.GetStreamAsync("https://aka.ms/vs/17/release/vc_redist.x64.exe");
|
var bytes = await CHttpClient.GetByteArrayAsync("https://aka.ms/vs/17/release/vc_redist.x64.exe");
|
||||||
await using var output = File.OpenWrite(pkgPath);
|
await File.WriteAllBytesAsync(pkgPath, bytes);
|
||||||
await stream.CopyToAsync(output);
|
|
||||||
Console.WriteLine(App.VcRuntimeInstalling);
|
Console.WriteLine(App.VcRuntimeInstalling);
|
||||||
_ = new Process {
|
using var process = new Process {
|
||||||
StartInfo = {
|
StartInfo = {
|
||||||
FileName = pkgPath,
|
FileName = pkgPath,
|
||||||
Arguments = "/install /passive /norestart"
|
Arguments = "/install /passive /norestart"
|
||||||
}
|
}
|
||||||
}.Start();
|
};
|
||||||
|
process.Start();
|
||||||
|
await process.WaitForExitAsync();
|
||||||
|
File.Delete(pkgPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public static class Native {
|
|||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern bool CloseHandle(IntPtr hObject);
|
public static extern bool CloseHandle(IntPtr hObject);
|
||||||
|
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern IntPtr CreateRemoteThread(
|
public static extern IntPtr CreateRemoteThread(
|
||||||
IntPtr hProcess,
|
IntPtr hProcess,
|
||||||
IntPtr lpThreadAttributes,
|
IntPtr lpThreadAttributes,
|
||||||
@@ -101,19 +101,19 @@ public static class Native {
|
|||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern IntPtr SetClipboardData(uint uFormat, IntPtr data);
|
public static extern IntPtr SetClipboardData(uint uFormat, IntPtr data);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool EmptyClipboard();
|
public static extern bool EmptyClipboard();
|
||||||
|
|
||||||
[DllImport("gdi32.dll")]
|
[DllImport("gdi32.dll", SetLastError = true)]
|
||||||
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern IntPtr GetDC(IntPtr hWnd);
|
public static extern IntPtr GetDC(IntPtr hWnd);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hdc);
|
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hdc);
|
||||||
|
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern uint WaitForSingleObject(IntPtr handle, ulong dwMilliseconds);
|
public static extern uint WaitForSingleObject(IntPtr handle, ulong dwMilliseconds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user