mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
93 lines
2.8 KiB
C#
93 lines
2.8 KiB
C#
|
|
using System.Runtime.InteropServices;
|
||
|
|
using System.Text;
|
||
|
|
|
||
|
|
namespace LanDesktopPLONDS.Installer;
|
||
|
|
|
||
|
|
internal static class InstallerStartupDiagnostics
|
||
|
|
{
|
||
|
|
private const uint MessageBoxIconError = 0x00000010;
|
||
|
|
private const uint MessageBoxOk = 0x00000000;
|
||
|
|
|
||
|
|
private static int _initialized;
|
||
|
|
private static int _fatalMessageShown;
|
||
|
|
|
||
|
|
public static string LogPath => Path.Combine(GetLogDirectory(), "startup.log");
|
||
|
|
|
||
|
|
public static void Initialize()
|
||
|
|
{
|
||
|
|
if (Interlocked.Exchange(ref _initialized, 1) != 0)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
|
||
|
|
{
|
||
|
|
var exception = args.ExceptionObject as Exception;
|
||
|
|
ReportFatal("The installer encountered an unhandled startup error.", exception);
|
||
|
|
};
|
||
|
|
|
||
|
|
TaskScheduler.UnobservedTaskException += (_, args) =>
|
||
|
|
{
|
||
|
|
ReportFatal("The installer encountered an unobserved background error.", args.Exception);
|
||
|
|
args.SetObserved();
|
||
|
|
};
|
||
|
|
|
||
|
|
Log("Startup diagnostics initialized.");
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Log(string message)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
Directory.CreateDirectory(GetLogDirectory());
|
||
|
|
File.AppendAllText(
|
||
|
|
LogPath,
|
||
|
|
$"[{DateTimeOffset.Now:O}] {message}{Environment.NewLine}",
|
||
|
|
Encoding.UTF8);
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
// Diagnostics must never become the reason the installer cannot start.
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void ReportFatal(string message, Exception? exception)
|
||
|
|
{
|
||
|
|
Log(exception is null ? message : $"{message}{Environment.NewLine}{exception}");
|
||
|
|
|
||
|
|
if (!OperatingSystem.IsWindows() || Interlocked.Exchange(ref _fatalMessageShown, 1) != 0)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var details = exception is null
|
||
|
|
? message
|
||
|
|
: $"{message}{Environment.NewLine}{Environment.NewLine}{exception.GetType().Name}: {exception.Message}";
|
||
|
|
_ = MessageBox(
|
||
|
|
IntPtr.Zero,
|
||
|
|
$"{details}{Environment.NewLine}{Environment.NewLine}Log: {LogPath}",
|
||
|
|
"LanDesktopPLONDS Installer",
|
||
|
|
MessageBoxOk | MessageBoxIconError);
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string GetLogDirectory()
|
||
|
|
{
|
||
|
|
var root = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||
|
|
if (string.IsNullOrWhiteSpace(root))
|
||
|
|
{
|
||
|
|
root = AppContext.BaseDirectory;
|
||
|
|
}
|
||
|
|
|
||
|
|
return Path.Combine(root, "LanMountainDesktop", "Installer", "logs");
|
||
|
|
}
|
||
|
|
|
||
|
|
[DllImport("user32.dll", EntryPoint = "MessageBoxW", CharSet = CharSet.Unicode)]
|
||
|
|
private static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
|
||
|
|
}
|