diff --git a/Source/NETworkManager.Models/Generated Files/CsWinRT/WinRTEventHelpers.cs b/Source/NETworkManager.Models/Generated Files/CsWinRT/WinRTEventHelpers.cs index 723dfc26f4..41efc07a13 100644 --- a/Source/NETworkManager.Models/Generated Files/CsWinRT/WinRTEventHelpers.cs +++ b/Source/NETworkManager.Models/Generated Files/CsWinRT/WinRTEventHelpers.cs @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------ // -// This file was generated by cswinrt.exe version 2.0.8.240703.1 +// This file was generated by cswinrt.exe version 2.1.3.240909.1 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs b/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs index 3f5fc1fd14..e6e408d2ee 100644 --- a/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs +++ b/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs @@ -1,7 +1,4 @@ -using System; -using System.IO; -using System.Linq; -using DnsClient; +using DnsClient; using Lextm.SharpSnmpLib.Messaging; using NETworkManager.Models; using NETworkManager.Models.Export; @@ -10,6 +7,9 @@ using NETworkManager.Models.PuTTY; using NETworkManager.Models.RemoteDesktop; using NETworkManager.Utilities; +using System; +using System.IO; +using System.Linq; // ReSharper disable InconsistentNaming @@ -22,8 +22,8 @@ public static class GlobalStaticConfiguration // Type to search (average type speed --> 187 chars/min) public static TimeSpan SearchDispatcherTimerTimeSpan => new(0, 0, 0, 0, 750); - // Status window delay in ms - public static int StatusWindowDelayBeforeOpen => 5000; + // Network config + public static int NetworkChangeDetectionDelay => 5000; // Profile config public static bool Profile_ExpandProfileView => true; diff --git a/Source/NETworkManager/Generated Files/CsWinRT/WinRTEventHelpers.cs b/Source/NETworkManager/Generated Files/CsWinRT/WinRTEventHelpers.cs index 723dfc26f4..41efc07a13 100644 --- a/Source/NETworkManager/Generated Files/CsWinRT/WinRTEventHelpers.cs +++ b/Source/NETworkManager/Generated Files/CsWinRT/WinRTEventHelpers.cs @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------ // -// This file was generated by cswinrt.exe version 2.0.8.240703.1 +// This file was generated by cswinrt.exe version 2.1.3.240909.1 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/Source/NETworkManager/MainWindow.xaml b/Source/NETworkManager/MainWindow.xaml index d3fb4a0ea5..76c5e17fb9 100644 --- a/Source/NETworkManager/MainWindow.xaml +++ b/Source/NETworkManager/MainWindow.xaml @@ -237,7 +237,7 @@ _flyoutRunCommandAreAnimationsEnabled; - set - { - if (value == _flyoutRunCommandAreAnimationsEnabled) - return; - - _flyoutRunCommandAreAnimationsEnabled = value; - OnPropertyChanged(); - } - } - private bool _isRestartRequired; public bool IsRestartRequired @@ -701,7 +686,7 @@ private void LoadApplicationList() // Select the application // Set application via command line, or select the default one, fallback to the first visible one var applicationList = Applications.Cast().ToArray(); - + if (CommandLineManager.Current.Application != ApplicationName.None) SelectedApplication = applicationList.FirstOrDefault(x => x.Name == CommandLineManager.Current.Application); else @@ -1244,7 +1229,6 @@ private void OpenRunAction() { ConfigurationManager.OnDialogOpen(); - FlyoutRunCommandAreAnimationsEnabled = true; FlyoutRunCommandIsOpen = true; } @@ -1259,7 +1243,7 @@ private void RunCommandDoAction() private void RunCommandCloseAction() { - RunCommandFlyoutClose().ConfigureAwait(false); + RunCommandFlyoutClose(); } #endregion @@ -1321,28 +1305,24 @@ private void RunCommandDo() } // Close the flyout - RunCommandFlyoutClose(true).ConfigureAwait(false); + RunCommandFlyoutClose(true); } /// /// Close the run command flyout and clear the search. /// - private async Task RunCommandFlyoutClose(bool clearSearch = false) + private void RunCommandFlyoutClose(bool clearSearch = false) { if (!FlyoutRunCommandIsOpen) return; - - FlyoutRunCommandAreAnimationsEnabled = false; + FlyoutRunCommandIsOpen = false; ConfigurationManager.OnDialogClose(); // Clear the search if (clearSearch) - { - await Task.Delay(500); // Wait for the animation to finish RunCommandSearch = string.Empty; - } } #endregion @@ -1360,7 +1340,7 @@ private void FlyoutRunCommand_IsKeyboardFocusWithinChanged(object sender, Depend if (e.NewValue is not false) return; - RunCommandFlyoutClose().ConfigureAwait(false); + RunCommandFlyoutClose(); } #endregion @@ -1946,7 +1926,7 @@ private async void OnNetworkHasChanged() _isNetworkChanging = true; // Wait, because the event may be triggered several times. - await Task.Delay(GlobalStaticConfiguration.StatusWindowDelayBeforeOpen); + await Task.Delay(GlobalStaticConfiguration.NetworkChangeDetectionDelay); Log.Info("Network availability or address has changed!"); diff --git a/Source/NETworkManager/StatusWindow.xaml.cs b/Source/NETworkManager/StatusWindow.xaml.cs index ffdbc2e1ca..a4184ca53b 100644 --- a/Source/NETworkManager/StatusWindow.xaml.cs +++ b/Source/NETworkManager/StatusWindow.xaml.cs @@ -4,6 +4,7 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Threading; +using log4net; using NETworkManager.Settings; using NETworkManager.Utilities; using NETworkManager.Views; @@ -42,7 +43,7 @@ private void OnPropertyChanged([CallerMemberName] string propertyName = null) #endregion #region Variables - + // Set priority to make the ui smoother private readonly DispatcherTimer _dispatcherTimerClose = new(DispatcherPriority.Normal); @@ -102,7 +103,7 @@ public int Time private void ReloadAction() { - Reload(); + Check(); } public ICommand ShowMainWindowCommand => new RelayCommand(_ => ShowMainWindowAction()); @@ -126,9 +127,9 @@ private void CloseAction() #region Methods - private void Reload() + private void Check() { - _networkConnectionView.Reload(); + _networkConnectionView.Check(); } /// @@ -137,19 +138,28 @@ private void Reload() /// Automatically close the window after a certain time. public void ShowWindow(bool enableCloseTimer = false) { - // Show on primary screen in left/bottom corner + // Set window position on primary screen // ToDo: User setting... - Left = Screen.PrimaryScreen.WorkingArea.Right - Width - 10; - Top = Screen.PrimaryScreen.WorkingArea.Bottom - Height - 10; + if (Screen.PrimaryScreen != null) + { + Left = Screen.PrimaryScreen.WorkingArea.Right - Width - 10; + Top = Screen.PrimaryScreen.WorkingArea.Bottom - Height - 10; + } + // Show the window Show(); - + + // Check the network connection + Check(); + + // Close the window after a certain time if (enableCloseTimer) { SetupCloseTimer(); return; } + // Focus the window Activate(); } diff --git a/Source/NETworkManager/ViewModels/DashboardViewModel.cs b/Source/NETworkManager/ViewModels/DashboardViewModel.cs index 4f56fd0f00..8bccf3a447 100644 --- a/Source/NETworkManager/ViewModels/DashboardViewModel.cs +++ b/Source/NETworkManager/ViewModels/DashboardViewModel.cs @@ -9,13 +9,16 @@ public DashboardViewModel() private void LoadSettings() { + } public void OnViewVisible() { + } public void OnViewHide() { + } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/IPApiDNSResolverWidgetViewModel.cs b/Source/NETworkManager/ViewModels/IPApiDNSResolverWidgetViewModel.cs index 016a95c6fa..027847f1d6 100644 --- a/Source/NETworkManager/ViewModels/IPApiDNSResolverWidgetViewModel.cs +++ b/Source/NETworkManager/ViewModels/IPApiDNSResolverWidgetViewModel.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; -using System.Net.NetworkInformation; -using System.Threading.Tasks; +using System.Threading.Tasks; using System.Windows.Input; using NETworkManager.Models.IPApi; using NETworkManager.Settings; @@ -10,23 +8,6 @@ namespace NETworkManager.ViewModels; public class IPApiDNSResolverWidgetViewModel : ViewModelBase { - #region Events - - private void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(SettingsInfo.Dashboard_CheckIPApiDNSResolver): - // Check if enabled via settings - if (SettingsManager.Current.Dashboard_CheckIPApiDNSResolver) - Check(); - - break; - } - } - - #endregion - #region Variables private bool _isRunning; @@ -65,18 +46,12 @@ private set public IPApiDNSResolverWidgetViewModel() { - // Detect if network address or status changed... - NetworkChange.NetworkAvailabilityChanged += (_, _) => Check(); - NetworkChange.NetworkAddressChanged += (_, _) => Check(); - LoadSettings(); - - // Detect if settings have changed... - SettingsManager.Current.PropertyChanged += SettingsManager_PropertyChanged; } private void LoadSettings() { + } #endregion diff --git a/Source/NETworkManager/ViewModels/IPApiIPGeolocationWidgetViewModel.cs b/Source/NETworkManager/ViewModels/IPApiIPGeolocationWidgetViewModel.cs index a81cda84a6..5f68a2c463 100644 --- a/Source/NETworkManager/ViewModels/IPApiIPGeolocationWidgetViewModel.cs +++ b/Source/NETworkManager/ViewModels/IPApiIPGeolocationWidgetViewModel.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; -using System.Net.NetworkInformation; -using System.Threading.Tasks; +using System.Threading.Tasks; using System.Windows.Input; using log4net; using NETworkManager.Models.IPApi; @@ -11,23 +9,6 @@ namespace NETworkManager.ViewModels; public class IPApiIPGeolocationWidgetViewModel : ViewModelBase { - #region Events - - private void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(SettingsInfo.Dashboard_CheckIPApiIPGeolocation): - // Check if enabled via settings - if (SettingsManager.Current.Dashboard_CheckIPApiIPGeolocation) - Check(); - - break; - } - } - - #endregion - #region Variables private static readonly ILog Log = LogManager.GetLogger(typeof(IPApiIPGeolocationWidgetViewModel)); @@ -68,14 +49,7 @@ private set public IPApiIPGeolocationWidgetViewModel() { - // Detect if network address or status changed... - NetworkChange.NetworkAvailabilityChanged += (_, _) => Check(); - NetworkChange.NetworkAddressChanged += (_, _) => Check(); - LoadSettings(); - - // Detect if settings have changed... - SettingsManager.Current.PropertyChanged += SettingsManager_PropertyChanged; } private void LoadSettings() diff --git a/Source/NETworkManager/ViewModels/NetworkConnectionWidgetViewModel.cs b/Source/NETworkManager/ViewModels/NetworkConnectionWidgetViewModel.cs index b820026a36..737ff23560 100644 --- a/Source/NETworkManager/ViewModels/NetworkConnectionWidgetViewModel.cs +++ b/Source/NETworkManager/ViewModels/NetworkConnectionWidgetViewModel.cs @@ -1,44 +1,23 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; +using NETworkManager.Models.Network; +using NETworkManager.Settings; +using NETworkManager.Utilities; +using System; using System.Net; using System.Net.Http; -using System.Net.NetworkInformation; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; -using NETworkManager.Models.Network; -using NETworkManager.Settings; -using NETworkManager.Utilities; +using log4net; using NetworkInterface = NETworkManager.Models.Network.NetworkInterface; namespace NETworkManager.ViewModels; public class NetworkConnectionWidgetViewModel : ViewModelBase { - #region Events - - private void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(SettingsInfo.Dashboard_CheckPublicIPAddress): - OnPropertyChanged(nameof(CheckPublicIPAddressEnabled)); - - // Check connection if enabled via settings - if (CheckPublicIPAddressEnabled) - CheckConnection(); - - break; - } - } - - #endregion - #region Variables + private static readonly ILog Log = LogManager.GetLogger(typeof(NetworkConnectionWidgetViewModel)); - private bool _isChecking; #region Computer @@ -465,14 +444,7 @@ private set public NetworkConnectionWidgetViewModel() { - // Detect if network address or status changed... - NetworkChange.NetworkAvailabilityChanged += (_, _) => CheckConnection(); - NetworkChange.NetworkAddressChanged += (_, _) => CheckConnection(); - LoadSettings(); - - // Detect if settings have changed... - SettingsManager.Current.PropertyChanged += SettingsManager_PropertyChanged; } private void LoadSettings() @@ -483,69 +455,83 @@ private void LoadSettings() #region ICommands & Actions - public ICommand CheckConnectionViaHotkeyCommand => new RelayCommand(_ => CheckConnectionViaHotkeyAction()); + public ICommand CheckViaHotkeyCommand => new RelayCommand(_ => CheckViaHotkeyAction()); - private void CheckConnectionViaHotkeyAction() + private void CheckViaHotkeyAction() { - CheckConnection(); + Check(); } #endregion #region Methods - public void CheckConnection() + public void Check() { - CheckConnectionAsync().ConfigureAwait(false); + CheckAsync().ConfigureAwait(false); } - private CancellationTokenSource _tokenSource; - private CancellationToken _ct; - - private async Task CheckConnectionAsync() - { - // Already in queue - if (_tokenSource is { IsCancellationRequested: true }) - return; - - // Cancel if running - if (_isChecking) - { - _tokenSource.Cancel(); - - while (_isChecking) await Task.Delay(250, _ct); + private bool _isChecking; + private CancellationTokenSource _cancellationTokenSource; + private Task _checkTask = Task.CompletedTask; + + private async Task CheckAsync() + { + Log.Info("Checking network connection..."); + + // Cancel previous checks if running + if(!_checkTask.IsCompleted) + { + Log.Info("Cancelling previous checks..."); + await _cancellationTokenSource.CancelAsync(); + + try + { + await _checkTask; + } + catch(OperationCanceledException) + { + Log.Info("Task was cancelled from previous checks."); + } + finally + { + _cancellationTokenSource.Dispose(); + } } - - // Start check + _isChecking = true; - - _tokenSource = new CancellationTokenSource(); - _ct = _tokenSource.Token; + _cancellationTokenSource = new CancellationTokenSource(); + bool wasCanceled = false; try { - await Task.Run(async () => - { - List tasks = new() - { - CheckConnectionComputerAsync(_ct), - CheckConnectionRouterAsync(_ct), - CheckConnectionInternetAsync(_ct) - }; - - await Task.WhenAll(tasks); - }, _tokenSource.Token); + _checkTask = RunTask(_cancellationTokenSource.Token); + await _checkTask; } catch (OperationCanceledException) { + wasCanceled = true; + Log.Info("Task was cancelled from current checks."); } finally { - _tokenSource.Dispose(); - _isChecking = false; + if (!wasCanceled) + { + _isChecking = false; + Log.Info("Network connection check completed."); + } } } - + + private async Task RunTask(CancellationToken ct) + { + await Task.WhenAll( + CheckConnectionComputerAsync(ct), + CheckConnectionRouterAsync(ct), + CheckConnectionInternetAsync(ct) + ); + } + private Task CheckConnectionComputerAsync(CancellationToken ct) { return Task.Run(async () => @@ -554,9 +540,11 @@ private Task CheckConnectionComputerAsync(CancellationToken ct) IsComputerIPv4Checking = true; ComputerIPv4 = ""; ComputerIPv4State = ConnectionState.None; + IsComputerIPv6Checking = true; ComputerIPv6 = ""; ComputerIPv6State = ConnectionState.None; + IsComputerDNSChecking = true; ComputerDNS = ""; ComputerDNSState = ConnectionState.None; @@ -875,6 +863,5 @@ private Task CheckConnectionInternetAsync(CancellationToken ct) IsInternetDNSChecking = false; }, ct); } - #endregion } \ No newline at end of file diff --git a/Source/NETworkManager/Views/DashboardView.xaml.cs b/Source/NETworkManager/Views/DashboardView.xaml.cs index c3f6632f74..9512c34509 100644 --- a/Source/NETworkManager/Views/DashboardView.xaml.cs +++ b/Source/NETworkManager/Views/DashboardView.xaml.cs @@ -6,24 +6,45 @@ public partial class DashboardView { private readonly DashboardViewModel _viewModel = new(); + private readonly NetworkConnectionWidgetView _networkConnectionWidgetView = new(); + private readonly IPApiIPGeolocationWidgetView _ipApiIPGeolocationWidgetView = new(); + private readonly IPApiDNSResolverWidgetView _ipApiDNSResolverWidgetView = new(); + + public DashboardView() { InitializeComponent(); DataContext = _viewModel; // Load views - ContentControlNetworkConnection.Content = new NetworkConnectionWidgetView(); - ContentControlIPApiIPGeolocation.Content = new IPApiIPGeolocationWidgetView(); - ContentControlIPApiDNSResolver.Content = new IPApiDNSResolverWidgetView(); + ContentControlNetworkConnection.Content = _networkConnectionWidgetView; + ContentControlIPApiIPGeolocation.Content = _ipApiIPGeolocationWidgetView; + ContentControlIPApiDNSResolver.Content = _ipApiDNSResolverWidgetView; + + // Check all widgets + Check(); + } + + public void OnViewVisible() + { + _viewModel.OnViewVisible(); + + // Check all widgets + Check(); } public void OnViewHide() { _viewModel.OnViewHide(); } - - public void OnViewVisible() + + /// + /// Check all widgets + /// + private void Check() { - _viewModel.OnViewVisible(); + _networkConnectionWidgetView.Check(); + _ipApiIPGeolocationWidgetView.Check(); + _ipApiDNSResolverWidgetView.Check(); } } \ No newline at end of file diff --git a/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml b/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml index ef277499e7..61cec61b2a 100644 --- a/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml +++ b/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml @@ -11,7 +11,7 @@ xmlns:viewModels="clr-namespace:NETworkManager.ViewModels" xmlns:system="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" MinHeight="200" - d:DataContext="{d:DesignInstance viewModels:IPApiDNSResolverWidgetViewModel}" Loaded="UserControl_Loaded"> + d:DataContext="{d:DesignInstance viewModels:IPApiDNSResolverWidgetViewModel}"> diff --git a/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml.cs b/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml.cs index b36a945e9c..3f6965507d 100644 --- a/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml.cs +++ b/Source/NETworkManager/Views/IPApiDNSResolverWidgetView.xaml.cs @@ -1,5 +1,4 @@ -using System.Windows; -using NETworkManager.ViewModels; +using NETworkManager.ViewModels; namespace NETworkManager.Views; @@ -13,7 +12,7 @@ public IPApiDNSResolverWidgetView() DataContext = _viewModel; } - private void UserControl_Loaded(object sender, RoutedEventArgs e) + public void Check() { _viewModel.Check(); } diff --git a/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml b/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml index ca769b03fd..389e13d83b 100644 --- a/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml +++ b/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml @@ -11,8 +11,7 @@ xmlns:settings="clr-namespace:NETworkManager.Settings;assembly=NETworkManager.Settings" xmlns:system="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" MinHeight="200" - d:DataContext="{d:DesignInstance viewModels:IPApiIPGeolocationWidgetViewModel}" - Loaded="UserControl_Loaded"> + d:DataContext="{d:DesignInstance viewModels:IPApiIPGeolocationWidgetViewModel}"> diff --git a/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml.cs b/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml.cs index 1566ca3623..54e004404a 100644 --- a/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml.cs +++ b/Source/NETworkManager/Views/IPApiIPGeolocationWidgetView.xaml.cs @@ -1,5 +1,4 @@ -using System.Windows; -using NETworkManager.ViewModels; +using NETworkManager.ViewModels; namespace NETworkManager.Views; @@ -13,7 +12,7 @@ public IPApiIPGeolocationWidgetView() DataContext = _viewModel; } - private void UserControl_Loaded(object sender, RoutedEventArgs e) + public void Check() { _viewModel.Check(); } diff --git a/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml b/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml index bd293f12ad..6414ee6ca2 100644 --- a/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml +++ b/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml @@ -9,9 +9,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewModels="clr-namespace:NETworkManager.ViewModels" mc:Ignorable="d" - d:DataContext="{d:DesignInstance viewModels:NetworkConnectionWidgetViewModel}" Loaded="UserControl_Loaded"> + d:DataContext="{d:DesignInstance viewModels:NetworkConnectionWidgetViewModel}"> - + diff --git a/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml.cs b/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml.cs index d9e826b18d..caf8c582f6 100644 --- a/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml.cs +++ b/Source/NETworkManager/Views/NetworkConnectionWidgetView.xaml.cs @@ -1,5 +1,4 @@ -using System.Windows; -using NETworkManager.ViewModels; +using NETworkManager.ViewModels; namespace NETworkManager.Views; @@ -13,13 +12,8 @@ public NetworkConnectionWidgetView() DataContext = _viewModel; } - public void Reload() + public void Check() { - _viewModel.CheckConnection(); - } - - private void UserControl_Loaded(object sender, RoutedEventArgs e) - { - _viewModel.CheckConnection(); + _viewModel.Check(); } } \ No newline at end of file