Initial commit: FluidExplorer:从零实现的 WinUI 3 文件资源管理器替代品(Mica、命令栏、面包屑)
This commit is contained in:
+94
@@ -0,0 +1,94 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user