BITKit/Packages/Core/Applation/BITApp.cs

200 lines
7.1 KiB
C#

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 AppIsNotPlayingException : Exception
{
public override string Message => "Application Is Not Playing";
}
public class BITApp
{
[System.Serializable]
public record AppSettings
{
public List<string> whiteList = new();
public List<string> 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<OpenPath>($"正在打开文件夹:{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<MethodInfo> excuteOnAwake;
static IEnumerable<MethodInfo> excuteOnStart;
static IEnumerable<MethodInfo> excuteOnStops;
public static async void Start(string appName = nameof(BITApp),AppSettings settings=default)
{
Settings = settings;
BIT4Log.Log<BITApp>($"正在创建应用:{appName}");
CancellationTokenSource = new();
AppName = appName;
ThreadHelper.LogCurrentThread();
await Init();
}
static async Task Init()
{
try
{
BIT4Log.Log<BITApp>($"已进入{AppName}");
if (State is not InitializationState.None)
{
BIT4Log.Warnning("警告:上次启动可能未正确退出");
State = InitializationState.None;
}
BIT4Log.Log<BITApp>($"正在初始化多线程Worker");
ThreadHelper.InitAPP();
BIT4Log.Log<BITApp>($"已初始化多线程Worker");
await UniTask.SwitchToThreadPool();
ThreadHelper.LogCurrentThread();
BIT4Log.Log<BITApp>($"正在创建计时器");
Stopwatch stopwatch = new();
stopwatch.Start();
BIT4Log.Log<BITApp>($"已创建计时器");
BIT4Log.Log<BITApp>($"正在初始化ReflectionHelper");
Stopwatch reflectionHelperWatch = new();
reflectionHelperWatch.Start();
ReflectionHelper.Init();
reflectionHelperWatch.Stop();
BIT4Log.Log<BITApp>($"已完成初始化ReflectionHelper,耗时:{reflectionHelperWatch.ElapsedMilliseconds}ms");
BIT4Log.Log<BITApp>($"正在加载ExcuteOnAwake");
excuteOnAwake = await ReflectionHelper.GetMethods<ExcuteOnAwakeAttribute>();
BIT4Log.Log<BITApp>($"正在加载ExcuteOnStart");
excuteOnStart = await ReflectionHelper.GetMethods<ExcuteOnStartAttribute>();
BIT4Log.Log<BITApp>($"正在加载ExcuteOnStop");
excuteOnStops = await ReflectionHelper.GetMethods<ExcuteOnStopAttribute>();
BIT4Log.Log<BITApp>($"正在调用 ExcuteOnAwake");
foreach (var x in excuteOnAwake)
{
x.Invoke(null, null);
if (CancellationTokenSource.IsCancellationRequested)
return;
}
BIT4Log.Log<BITApp>($"正在调用 ExcuteOnStart");
foreach (var x in excuteOnStart)
{
x.Invoke(null, null);
if (CancellationTokenSource.IsCancellationRequested)
return;
}
stopwatch.Stop();
State = InitializationState.Initialized;
BIT4Log.Log<BITApp>($"初始化耗时:{stopwatch.ElapsedMilliseconds}ms");
BIT4Log.Log<BITApp>($"已完成初始化");
}
catch (System.Exception e)
{
BIT4Log.Warnning<BITApp>($"{nameof(BITApp)}初始化错误:");
BIT4Log.LogException(e);
}
}
public static async Task Stop()
{
BIT4Log.Log<BITApp>($"正在停止{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<BITApp>($"已停止{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();
}
}
}
}