Files
better-genshin-impact/BetterGenshinImpact/Helpers/RuntimeHelper.cs
mfkvfhpdx 468a54e037 执行调度器任务增加继续执行功能 (#1658)
* 完全跳过的配置组,不发送通知。给周期配置增加说明。

* 启动参数增加 --no-single ,允许多开,实现特殊需求(重启需要)。增加了一个重启bgi的方法。增加了任务进度的功能,执行调度器任务时,会记录当前任务执行位置,当关闭后(比如F11),下次可以通过继续菜单,选择记录,从上次关闭任务处执行。

* 调整继续执行,最后一次成功的下一个任务执行

* 设置,其他设置,增加了调度器任务,遇到异常时,连续累计一定次数时,重启BGI,和可配置的重启游戏。

* 连续任务支持循环,右键支持从连续的某一个任务开始执行。修改了一些配置变量的写法,使之不会保存到json文件中。
2025-06-02 00:03:26 +08:00

174 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.GameTask;
using Microsoft.Extensions.Hosting;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
namespace BetterGenshinImpact.Helpers;
internal static class RuntimeHelper
{
public static bool IsElevated { get; } = GetElevated();
public static bool IsDebuggerAttached => Debugger.IsAttached;
public static bool IsDesignMode { get; } = GetDesignMode();
public static bool IsDebug =>
#if DEBUG
true;
#else
false;
#endif
private static bool GetElevated()
{
using WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
private static bool GetDesignMode()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
else if (Process.GetCurrentProcess().ProcessName == "devenv")
{
return true;
}
return false;
}
public static void EnsureElevated()
{
if (!IsElevated)
{
RestartAsElevated();
}
}
public static string ReArguments()
{
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
for (int i = default; i < args.Length; i++)
{
args[i] = $@"""{args[i]}""";
}
return string.Join(" ", args);
}
public static void RestartAsElevated(string fileName = null!, string dir = null!, string args = null!, int? exitCode = null, bool forced = false)
{
try
{
ProcessStartInfo startInfo = new()
{
UseShellExecute = true,
WorkingDirectory = dir ?? Global.StartUpPath,
FileName = fileName ?? "BetterGI.exe",
Arguments = args ?? ReArguments(),
Verb = "runas"
};
try
{
_ = Process.Start(startInfo);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
MessageBox.Error("以管理员权限启动 BetterGI 失败,非管理员权限下所有模拟操作功能均不可用!\r\n请尝试 右键 —— 以管理员身份运行 的方式启动 BetterGI");
return;
}
}
catch (Win32Exception)
{
return;
}
if (forced)
{
Process.GetCurrentProcess().Kill();
}
Environment.Exit(exitCode ?? 'r' + 'u' + 'n' + 'a' + 's');
}
public static void CheckSingleInstance(string instanceName, Action<bool> callback = null!)
{
EventWaitHandle? handle;
try
{
handle = EventWaitHandle.OpenExisting(instanceName);
handle.Set();
callback?.Invoke(false);
Environment.Exit(0xFFFF);
}
catch (WaitHandleCannotBeOpenedException)
{
callback?.Invoke(true);
handle = new EventWaitHandle(false, EventResetMode.AutoReset, instanceName);
}
_ = Task.Factory.StartNew(() =>
{
while (handle.WaitOne())
{
Application.Current.Dispatcher?.BeginInvoke(() =>
{
Application.Current.MainWindow?.Show();
Application.Current.MainWindow?.Activate();
SystemControl.RestoreWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);
});
}
}, TaskCreationOptions.LongRunning).ConfigureAwait(false);
}
public static void CheckIntegration()
{
if (!Directory.Exists(Global.Absolute("Assets")) || !Directory.Exists(Global.Absolute("GameTask")))
{
StringBuilder stringBuilder = new("发现有关键文件缺失,");
stringBuilder.Append(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) == Global.StartUpPath
? "请不要把主程序exe文件剪切到桌面。正确的做法请右键点击主程序在弹出的菜单中选择“发送到”选项然后选择“桌面创建快捷方式”。"
: "请重新安装软件");
MessageBox.Warning(stringBuilder.ToString());
Environment.Exit(0xFFFF);
}
}
}
internal static class RuntimeExtension
{
public static IHostBuilder UseElevated(this IHostBuilder app)
{
RuntimeHelper.EnsureElevated();
return app;
}
public static IHostBuilder UseSingleInstance(this IHostBuilder self, string instanceName, Action<bool> callback = null!)
{
if (!Environment.GetCommandLineArgs().Contains("--no-single"))
{
RuntimeHelper.CheckSingleInstance(instanceName, callback);
}
return self;
}
public static IHostBuilder CheckIntegration(this IHostBuilder app)
{
RuntimeHelper.CheckIntegration();
return app;
}
}