using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.Reflection; using Cysharp.Threading.Tasks; using System.Threading; using System.IO; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace BITKit { public class BITApp { [System.Serializable] public record AppSettings { public List whiteList = new(); public List blackList = new(); } [System.Serializable] public class OpenPath : IAction, IDisposable { public string path; public void Dispose() { path = null; } public void Excute() { path = path.Replace(@"/", @"\"); 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 Excute() { 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); public static CancellationTokenSource CancellationTokenSource = new(); public static InitializationState State; public static Assembly[] Assemblies; public static AppSettings Settings { get; protected set; } static IEnumerable excuteOnAwake; static IEnumerable excuteOnStart; static IEnumerable excuteOnStops; public static async void Start(string appName = nameof(BITApp),AppSettings settings=default) { Settings = settings; BIT4Log.Log($"正在创建应用:{appName}"); CancellationTokenSource = new(); AppName = appName; ThreadHelper.LogCurrentThread(); await Init(); } static async Task Init() { try { BIT4Log.Log($"已进入{AppName}"); if (State is not InitializationState.None) { BIT4Log.Warnning("警告:上次启动可能未正确退出"); State = InitializationState.None; } BIT4Log.Log($"正在初始化多线程Worker"); ThreadHelper.InitAPP(); BIT4Log.Log($"已初始化多线程Worker"); await UniTask.SwitchToThreadPool(); ThreadHelper.LogCurrentThread(); BIT4Log.Log($"正在创建计时器"); Stopwatch stopwatch = new(); stopwatch.Start(); BIT4Log.Log($"已创建计时器"); BIT4Log.Log($"正在初始化ReflectionHelper"); Stopwatch reflectionHelperWatch = new(); reflectionHelperWatch.Start(); ReflectionHelper.Init(); reflectionHelperWatch.Stop(); BIT4Log.Log($"已完成初始化ReflectionHelper,耗时:{reflectionHelperWatch.ElapsedMilliseconds}ms"); BIT4Log.Log($"正在加载ExcuteOnAwake"); excuteOnAwake = await ReflectionHelper.GetMethods(); BIT4Log.Log($"正在加载ExcuteOnStart"); excuteOnStart = await ReflectionHelper.GetMethods(); BIT4Log.Log($"正在加载ExcuteOnStop"); excuteOnStops = await ReflectionHelper.GetMethods(); BIT4Log.Log($"正在调用 ExcuteOnAwake"); foreach (var x in excuteOnAwake) { x.Invoke(null, null); if (CancellationTokenSource.IsCancellationRequested) return; } BIT4Log.Log($"正在调用 ExcuteOnStart"); foreach (var x in excuteOnStart) { x.Invoke(null, null); if (CancellationTokenSource.IsCancellationRequested) return; } stopwatch.Stop(); State = InitializationState.Initialized; BIT4Log.Log($"初始化耗时:{stopwatch.ElapsedMilliseconds}ms"); BIT4Log.Log($"已完成初始化"); } catch (System.Exception e) { BIT4Log.Warnning($"{nameof(BITApp)}初始化错误:"); BIT4Log.LogException(e); } } public static async Task Stop() { BIT4Log.Log($"正在停止{nameof(BITApp)}"); CancellationTokenSource.Cancel(); try { foreach (var x in excuteOnStops) { x.Invoke(null, null); } } catch (System.Exception e) { if (e is not NullReferenceException) BIT4Log.LogException(e); } await UniTask.Yield(); CancellationTokenSource = default; State = InitializationState.None; BIT4Log.Log($"已停止{nameof(BITApp)}"); } public static void Run(string path, string WorkingDirectory = "") { using (var open = new OpenAPP() { path = path, WorkingDirectory = WorkingDirectory }) { open.Excute(); } } public static void Open(string path) { using (var open = new OpenPath() { path = path }) { open.Excute(); } } } }