diff --git a/v2rayN/ServiceLib/Enums/EViewAction.cs b/v2rayN/ServiceLib/Enums/EViewAction.cs index 7677c6e9..2c47d31d 100644 --- a/v2rayN/ServiceLib/Enums/EViewAction.cs +++ b/v2rayN/ServiceLib/Enums/EViewAction.cs @@ -15,7 +15,6 @@ public enum EViewAction ShowHideWindow, ScanScreenTask, ScanImageTask, - Shutdown, BrowseServer, ImportRulesFromFile, InitSettingFont, diff --git a/v2rayN/ServiceLib/Handler/AppEvents.cs b/v2rayN/ServiceLib/Handler/AppEvents.cs index f61053ae..109ee762 100644 --- a/v2rayN/ServiceLib/Handler/AppEvents.cs +++ b/v2rayN/ServiceLib/Handler/AppEvents.cs @@ -13,6 +13,8 @@ public static class AppEvents public static readonly Subject AppExitRequested = new(); + public static readonly Subject ShutdownRequested = new(); + public static readonly Subject AdjustMainLvColWidthRequested = new(); public static readonly Subject DispatcherStatisticsRequested = new(); diff --git a/v2rayN/ServiceLib/Manager/AppManager.cs b/v2rayN/ServiceLib/Manager/AppManager.cs index 6cf0e826..33125289 100644 --- a/v2rayN/ServiceLib/Manager/AppManager.cs +++ b/v2rayN/ServiceLib/Manager/AppManager.cs @@ -1,3 +1,5 @@ +using System.Reactive; + namespace ServiceLib.Manager; public sealed class AppManager @@ -34,7 +36,7 @@ public sealed class AppManager #endregion Property - #region Init + #region App public bool InitApp() { @@ -87,7 +89,40 @@ public sealed class AppManager return true; } - #endregion Init + public async Task AppExitAsync(bool needShutdown) + { + try + { + Logging.SaveLog("AppExitAsync Begin"); + + await SysProxyHandler.UpdateSysProxy(_config, true); + AppEvents.AppExitRequested.OnNext(Unit.Default); + await Task.Delay(50); //Wait for AppExitRequested to be processed + + await ConfigHandler.SaveConfig(_config); + await ProfileExManager.Instance.SaveTo(); + await StatisticsManager.Instance.SaveTo(); + await CoreManager.Instance.CoreStop(); + StatisticsManager.Instance.Close(); + + Logging.SaveLog("AppExitAsync End"); + } + catch { } + finally + { + if (needShutdown) + { + Shutdown(false); + } + } + } + + public void Shutdown(bool byUser) + { + AppEvents.ShutdownRequested.OnNext(byUser); + } + + #endregion App #region Config diff --git a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs index e258d3b2..80336c5d 100644 --- a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs @@ -136,8 +136,7 @@ public class BackupAndRestoreViewModel : MyReactiveObject var result = await CreateZipFileFromDirectory(fileBackup); if (result) { - var service = Locator.Current.GetService(); - await service?.MyAppExitAsync(true); + await AppManager.Instance.AppExitAsync(false); await SQLiteHelper.Instance.DisposeDbConnectionAsync(); var toPath = Utils.GetConfigPath(); @@ -154,7 +153,7 @@ public class BackupAndRestoreViewModel : MyReactiveObject _ = ProcUtils.ProcessStart(upgradeFileName, Global.RebootAs, Utils.StartupPath()); } } - service?.Shutdown(true); + AppManager.Instance.Shutdown(true); } else { diff --git a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs index 579a2288..23839141 100644 --- a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs @@ -236,12 +236,19 @@ public class CheckUpdateViewModel : MyReactiveObject { return; } - if (!Utils.UpgradeAppExists(out _)) + if (!Utils.UpgradeAppExists(out var upgradeFileName)) { await UpdateView(_v2rayN, ResUI.UpgradeAppNotExistTip); + NoticeManager.Instance.SendMessageAndEnqueue(ResUI.UpgradeAppNotExistTip); + Logging.SaveLog("UpgradeApp does not exist"); return; } - Locator.Current.GetService()?.UpgradeApp(fileName); + + var id = ProcUtils.ProcessStart(upgradeFileName, fileName, Utils.StartupPath()); + if (id > 0) + { + await AppManager.Instance.AppExitAsync(true); + } } catch (Exception ex) { diff --git a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 45b8ffa7..7df04380 100644 --- a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -282,59 +282,11 @@ public class MainWindowViewModel : MyReactiveObject AppEvents.DispatcherStatisticsRequested.OnNext(update); } - public async Task MyAppExitAsync(bool blWindowsShutDown) - { - try - { - Logging.SaveLog("MyAppExitAsync Begin"); - - await SysProxyHandler.UpdateSysProxy(_config, true); - AppEvents.AppExitRequested.OnNext(Unit.Default); - - await ConfigHandler.SaveConfig(_config); - await ProfileExManager.Instance.SaveTo(); - await StatisticsManager.Instance.SaveTo(); - await CoreManager.Instance.CoreStop(); - StatisticsManager.Instance.Close(); - - Logging.SaveLog("MyAppExitAsync End"); - } - catch { } - finally - { - if (!blWindowsShutDown) - { - _updateView?.Invoke(EViewAction.Shutdown, false); - } - } - } - - public async Task UpgradeApp(string arg) - { - if (!Utils.UpgradeAppExists(out var upgradeFileName)) - { - NoticeManager.Instance.SendMessageAndEnqueue(ResUI.UpgradeAppNotExistTip); - Logging.SaveLog("UpgradeApp does not exist"); - return; - } - - var id = ProcUtils.ProcessStart(upgradeFileName, arg, Utils.StartupPath()); - if (id > 0) - { - await MyAppExitAsync(false); - } - } - public void ShowHideWindow(bool? blShow) { _updateView?.Invoke(EViewAction.ShowHideWindow, blShow); } - public void Shutdown(bool byUser) - { - _updateView?.Invoke(EViewAction.Shutdown, byUser); - } - #endregion Actions #region Servers && Groups @@ -517,7 +469,7 @@ public class MainWindowViewModel : MyReactiveObject public async Task RebootAsAdmin() { ProcUtils.RebootAsAdmin(); - await MyAppExitAsync(false); + await AppManager.Instance.AppExitAsync(true); } private async Task ClearServerStatistics() diff --git a/v2rayN/v2rayN.Desktop/App.axaml.cs b/v2rayN/v2rayN.Desktop/App.axaml.cs index a1b97b77..5303eb6c 100644 --- a/v2rayN/v2rayN.Desktop/App.axaml.cs +++ b/v2rayN/v2rayN.Desktop/App.axaml.cs @@ -74,11 +74,7 @@ public partial class App : Application private async void MenuExit_Click(object? sender, EventArgs e) { - var service = Locator.Current.GetService(); - if (service != null) - { - await service.MyAppExitAsync(true); - } - service?.Shutdown(true); + await AppManager.Instance.AppExitAsync(false); + AppManager.Instance.Shutdown(true); } } diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 417bbb9f..582b18ac 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -148,6 +148,12 @@ public partial class MainWindow : WindowBase .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); + + AppEvents.ShutdownRequested + .AsObservable() + .ObserveOn(RxApp.MainThreadScheduler) + .Subscribe(content => Shutdown(content)) + .DisposeWith(disposables); }); if (Utils.IsWindows()) @@ -222,19 +228,6 @@ public partial class MainWindow : WindowBase DispatcherPriority.Default); break; - case EViewAction.Shutdown: - if (obj != null && _blCloseByUser == false) - { - _blCloseByUser = (bool)obj; - } - StorageUI(); - if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - HotkeyManager.Instance.Dispose(); - desktop.Shutdown(); - } - break; - case EViewAction.ScanScreenTask: await ScanScreenTaskAsync(); break; @@ -289,10 +282,7 @@ public partial class MainWindow : WindowBase break; case WindowCloseReason.ApplicationShutdown or WindowCloseReason.OSShutdown: - if (ViewModel != null) - { - await ViewModel.MyAppExitAsync(true); - } + await AppManager.Instance.AppExitAsync(false); break; } @@ -387,9 +377,21 @@ public partial class MainWindow : WindowBase _blCloseByUser = true; StorageUI(); - if (ViewModel != null) + + await AppManager.Instance.AppExitAsync(true); + } + + private void Shutdown(bool obj) + { + if (obj is bool b && _blCloseByUser == false) { - await ViewModel.MyAppExitAsync(false); + _blCloseByUser = b; + } + StorageUI(); + if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + HotkeyManager.Instance.Dispose(); + desktop.Shutdown(); } } diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs index b9868edf..a3a26c97 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -145,6 +145,12 @@ public partial class MainWindow .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); + + AppEvents.ShutdownRequested + .AsObservable() + .ObserveOn(RxApp.MainThreadScheduler) + .Subscribe(content => Shutdown(content)) + .DisposeWith(disposables); }); this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; @@ -212,13 +218,6 @@ public partial class MainWindow }), DispatcherPriority.Normal); break; - case EViewAction.Shutdown: - Application.Current?.Dispatcher.Invoke((() => - { - Application.Current.Shutdown(); - }), DispatcherPriority.Normal); - break; - case EViewAction.ScanScreenTask: await ScanScreenTaskAsync(); break; @@ -266,7 +265,12 @@ public partial class MainWindow { Logging.SaveLog("Current_SessionEnding"); StorageUI(); - await ViewModel?.MyAppExitAsync(true); + await AppManager.Instance.AppExitAsync(false); + } + + private void Shutdown(bool obj) + { + Application.Current.Shutdown(); } private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e) diff --git a/v2rayN/v2rayN/Views/StatusBarView.xaml.cs b/v2rayN/v2rayN/Views/StatusBarView.xaml.cs index a4fcef55..2bc4c7c9 100644 --- a/v2rayN/v2rayN/Views/StatusBarView.xaml.cs +++ b/v2rayN/v2rayN/Views/StatusBarView.xaml.cs @@ -97,9 +97,7 @@ public partial class StatusBarView private async void menuExit_Click(object sender, RoutedEventArgs e) { tbNotify.Dispose(); - var service = Locator.Current.GetService(); - if (service != null) - await service.MyAppExitAsync(false); + await AppManager.Instance.AppExitAsync(true); } private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)