95 lines
3.4 KiB
C#
95 lines
3.4 KiB
C#
using FluidExplorer.Services;
|
|
using Microsoft.UI.Dispatching;
|
|
using Microsoft.UI.Xaml;
|
|
|
|
namespace FluidExplorer;
|
|
|
|
public partial class App : Application
|
|
{
|
|
/// <summary>启动阶段日志:WinUI 启动期的异常在窗口出现前就终止进程,必须落盘才能定位。</summary>
|
|
private static readonly string LogPath = Path.Combine(AppContext.BaseDirectory, "startup.log");
|
|
|
|
public App()
|
|
{
|
|
Log("App ctor: begin");
|
|
InitializeComponent();
|
|
Log("App ctor: InitializeComponent done");
|
|
UnhandledException += OnUnhandledException;
|
|
AppDomain.CurrentDomain.UnhandledException += (_, e) => Log($"AppDomain unhandled: {e.ExceptionObject}");
|
|
TaskScheduler.UnobservedTaskException += (_, e) =>
|
|
{
|
|
Log($"Unobserved task exception: {e.Exception}");
|
|
e.SetObserved();
|
|
};
|
|
|
|
// 诊断开关:宿主/非托管路径上的异常不会走 UnhandledException,需要首次异常钩子才能看到来源
|
|
if (Environment.GetEnvironmentVariable("FLUID_DEBUG_EXPLOG") == "1")
|
|
{
|
|
AppDomain.CurrentDomain.FirstChanceException += (_, e) =>
|
|
{
|
|
var ex = e.Exception;
|
|
var stack = ex.StackTrace ?? string.Empty;
|
|
if (stack.Contains("FluidExplorer", StringComparison.Ordinal) || ex.Source?.Contains("FluidExplorer", StringComparison.Ordinal) == true)
|
|
Log($"first-chance {ex.GetType().FullName}: {ex.Message}{Environment.NewLine}{stack}");
|
|
};
|
|
}
|
|
}
|
|
|
|
public static AppServices Services { get; private set; } = null!;
|
|
|
|
/// <summary>当前主窗口(原版右键菜单、窗口图标、对话框都需要它的 HWND / XamlRoot)。</summary>
|
|
public static MainWindow MainWindowInstance { get; private set; } = null!;
|
|
|
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
|
{
|
|
try
|
|
{
|
|
Log("OnLaunched: begin");
|
|
Services = new AppServices(DispatcherQueue.GetForCurrentThread());
|
|
Log("OnLaunched: services ready");
|
|
Services.WireSearchIndex();
|
|
Log("OnLaunched: search index wired");
|
|
|
|
MainWindowInstance = new MainWindow(Services);
|
|
Log("OnLaunched: window constructed");
|
|
MainWindowInstance.Activate();
|
|
Log("OnLaunched: window activated");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"OnLaunched FAILED: {ex}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
internal static void Log(string message)
|
|
{
|
|
try
|
|
{
|
|
File.AppendAllText(LogPath, $"[{DateTime.Now:HH:mm:ss.fff}] {message}{Environment.NewLine}");
|
|
}
|
|
catch
|
|
{
|
|
// 日志失败绝不能影响主流程
|
|
}
|
|
}
|
|
|
|
private static void OnUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
|
{
|
|
Log($"XAML unhandled: {e.Message}{Environment.NewLine}{e.Exception}");
|
|
try
|
|
{
|
|
var log = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
|
"FluidExplorer", "crash.log");
|
|
Directory.CreateDirectory(Path.GetDirectoryName(log)!);
|
|
File.AppendAllText(log, $"[{DateTime.Now:O}] {e.Message}\n{e.Exception}\n\n");
|
|
}
|
|
catch
|
|
{
|
|
// 忽略
|
|
}
|
|
e.Handled = true;
|
|
}
|
|
}
|