XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

LumaTunnel

【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。

公开
关注 0 Fork 0 Star 0
UTF-8
using Microsoft.UI.Xaml;

namespace LumaTunnel.Client;

public partial class App : Application, IDisposable
{
    private readonly Mutex _singleInstance;
    private bool _ownsMutex;
    public static App CurrentApp => (App)Current;
    public static MainWindow? MainWindow { get; private set; }
    public bool IsExiting { get; private set; }

    public App()
    {
        _singleInstance = new Mutex(true, @"Local\LumaTunnel.Client.SingleInstance", out _ownsMutex);
        if (!_ownsMutex)
        {
            Environment.Exit(0);
            return;
        }
        InitializeComponent();
        UnhandledException += OnUnhandledException;
        AppDomain.CurrentDomain.UnhandledException += (_, _) => AppServices.SystemProxy.EmergencyRestore();
        AppDomain.CurrentDomain.ProcessExit += (_, _) => AppServices.SystemProxy.EmergencyRestore();
    }

    protected override async void OnLaunched(LaunchActivatedEventArgs args)
    {
        try
        {
            await AppServices.InitializeAsync();
            MainWindow = new MainWindow();
            MainWindow.Activate();
            AppServices.RootNavigation.Navigate(typeof(Views.StartupLoadingPage));
            AppServices.Tray.Initialize(MainWindow, MainWindow.ShowFromTray);
            if (Environment.GetCommandLineArgs().Contains("--background", StringComparer.OrdinalIgnoreCase))
                MainWindow.AppWindow.Hide();
        }
        catch (Exception exception)
        {
            Utilities.AppLog.Write("ERROR", "Client startup failed.", exception);
            AppServices.SystemProxy.EmergencyRestore();
            System.Diagnostics.Debug.WriteLine(exception);
            Exit();
        }
    }

    public async Task RequestExitAsync()
    {
        if (IsExiting) return;
        IsExiting = true;
        await AppServices.ShutdownAsync();
        if (_ownsMutex)
        {
            _singleInstance.ReleaseMutex();
            _ownsMutex = false;
        }
        _singleInstance.Dispose();
        Exit();
    }

    private static void OnUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(e.Exception);
        Utilities.AppLog.Write("ERROR", "Unhandled UI exception.", e.Exception);
        AppServices.SystemProxy.EmergencyRestore();
        e.Handled = true;
    }

    public void Dispose()
    {
        if (_ownsMutex)
        {
            _singleInstance.ReleaseMutex();
            _ownsMutex = false;
        }
        _singleInstance.Dispose();
        GC.SuppressFinalize(this);
    }
}