using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using Cysharp.Threading.Tasks; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; #if NET5_0_OR_GREATER using Microsoft.Extensions.DependencyInjection; #endif namespace BITKit { public class AppIsNotPlayingException : Exception { public override string Message => "Application Is Not Playing"; } public class BITApp { public static class Time { public static float DeltaTime { get; internal set; } public static double TimeAsDouble { get; internal set; } } [System.Serializable] public record AppSettings { public bool AllowInitialize = true; public List whiteList = new(); public List blackList = new() { "System", "Unity", "UnityEngine", "Microsoft", "Godot", "Internal", "GodotPlugins", // ReSharper disable once StringLiteralTypo "Cysharp", "kcp2k", "Swashbuckle", "Newtonsoft", "Lightbug", "NiceIO", "AndroidPlayerBuildProgram", "Steamworks", "AYellowpaper", "Utilities", "mattatz", "AmazingAssets", "MeshCombineStudio", "kcp2k", "AYellowpaper", "MudBlazor", "TextCopy", "Blazored", "TextCopy", "mattatz" }; } #if NET5_0_OR_GREATER /// /// 依赖服务集合 /// public static ServiceCollection ServiceCollection { get; internal set; } = new(); /// /// 依赖服务提供接口 /// public static ServiceProvider ServiceProvider { get; internal set; } /// /// 服务创建后的回调 /// public static Action OnServiceProviderBuilded; #endif /// /// 主线程 /// public static SynchronizationContext SynchronizationContext { get; private set; } [System.Serializable] public class OpenPath : IAction, IDisposable { public string path; public void Dispose() { path = null; } public void Execute() { //path = string.IsNullOrEmpty(path) ? Environment.CurrentDirectory : path.Replace(@"/", @"\"); var path = Environment.ExpandEnvironmentVariables(this.path); path = string.IsNullOrEmpty(path) ? Environment.CurrentDirectory : System.IO.Path.Combine(Environment.CurrentDirectory, path); BIT4Log.Log($"正在打开文件夹:{path}"); try { var process = Process.Start("explorer.exe", path); SwitchToThisWindow(process.MainWindowHandle, true); } catch (System.Exception e) { BIT4Log.LogException(e); } } } [System.Serializable] public class OpenAPP : IAction, IDisposable { public string path; public string WorkingDirectory; public void Dispose() { path = WorkingDirectory = null; } public void Execute() { if (File.Exists(path)) { ProcessStartInfo startInfo = new(path) { UseShellExecute = true }; if (string.IsNullOrEmpty(WorkingDirectory) is false) { startInfo.WorkingDirectory = WorkingDirectory; } var process = Process.Start(startInfo); SwitchToThisWindow(process.MainWindowHandle, true); } } } [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool SwitchToThisWindow(IntPtr hWnd, bool fAltTab); public static string AppName { get; private set; } = nameof(BITApp); private static CancellationTokenSource CancellationTokenSource = new(); public static CancellationToken CancellationToken => CancellationTokenSource.Token; public static InitializationState State; public static Assembly[] Assemblies; public static AppSettings Settings { get; protected set; } public static async void Start(string appName = nameof(BITApp),AppSettings settings=default) { Time.TimeAsDouble = 0; Time.DeltaTime = 1 / 60f; SynchronizationContext=SynchronizationContext.Current; Settings = settings??new AppSettings(); CancellationTokenSource = new CancellationTokenSource(); AppName = appName; ThreadHelper.LogCurrentThread(); await Init(); } private static async Task Init() { try { if (State is not InitializationState.None) { BIT4Log.Warning("警告:上次启动可能未正确退出"); return; } //加载app-settings.json var appSettingsPath = Path.Combine(Environment.CurrentDirectory, "appsettings.json"); if (PathHelper.TryGetText(appSettingsPath,out var json)) { DataParser.Set(json); BIT4Log.Log("已加载全局appsettings"); } //内部反射初始化 ThreadHelper.InitAPP(); await UniTask.SwitchToThreadPool(); ThreadHelper.LogCurrentThread(); Stopwatch stopwatch = new(); stopwatch.Start(); Stopwatch reflectionHelperWatch = new(); reflectionHelperWatch.Start(); await ReflectionHelper.Init(); reflectionHelperWatch.Stop(); stopwatch.Stop(); State = InitializationState.Initialized; BIT4Log.Log($"已完成初始化,耗时:{stopwatch.ElapsedMilliseconds}ms"); } catch (System.Exception e) { BIT4Log.Warning($"{nameof(BITApp)}初始化错误:"); BIT4Log.LogException(e); } } public static void Stop() { BIT4Log.Log($"正在停止{nameof(BITApp)}"); CancellationTokenSource.Cancel(); State = InitializationState.None; BIT4Log.Log($"已停止{nameof(BITApp)}"); BIT4Log.Log("Exit Code:0"); } public static void Run(string path, string WorkingDirectory = "") { using var open = new OpenAPP() { path = path, WorkingDirectory = WorkingDirectory }; open.Execute(); } public static void Open(string path) { using var open = new OpenPath() { path = path }; open.Execute(); } } }