diff --git a/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml b/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml
index 8d35b5e..3cba429 100644
--- a/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml
+++ b/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml
@@ -29,6 +29,7 @@
+
@@ -75,6 +76,7 @@
+
diff --git a/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml.cs b/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml.cs
index 2c1c7f9..b2a7b9d 100644
--- a/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml.cs
+++ b/EonaCat.PortMonitor/ConnectionDetailsWindow.xaml.cs
@@ -1,4 +1,6 @@
-using System.Windows;
+using System.Diagnostics;
+using System.Windows;
+using MessageBox = System.Windows.MessageBox;
namespace EonaCat.PortMonitor
{
@@ -7,10 +9,13 @@ namespace EonaCat.PortMonitor
///
public partial class ConnectionDetailsWindow : Window
{
+ private ConnectionInfo _currentConnection;
+
public ConnectionDetailsWindow(ConnectionInfo conn)
{
InitializeComponent();
+ _currentConnection = conn;
ProtocolText.Text = conn.Protocol;
LocalAddressText.Text = conn.LocalAddress;
LocalPortText.Text = conn.LocalPort.ToString();
@@ -45,5 +50,22 @@ namespace EonaCat.PortMonitor
{
Dispatcher.Invoke(() => ConnectionDurationText.Text = Convert.ToString(conn.FormattedConnectionDuration));
}
+
+ private void btnProcessPath_Click(object sender, RoutedEventArgs e)
+ {
+ // Open the process path in explorer
+ try
+ {
+ var process = Process.GetProcessById(_currentConnection.ProcessId);
+ if (process != null && process.MainModule != null)
+ {
+ Process.Start("explorer.exe", $"/select, \"{process.MainModule.FileName}\"");
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Failed to get process path: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
}
}
diff --git a/EonaCat.PortMonitor/ConnectionInfo.cs b/EonaCat.PortMonitor/ConnectionInfo.cs
new file mode 100644
index 0000000..9210e2b
--- /dev/null
+++ b/EonaCat.PortMonitor/ConnectionInfo.cs
@@ -0,0 +1,43 @@
+using System.ComponentModel;
+
+namespace EonaCat.PortMonitor
+{
+ public class ConnectionInfo : INotifyPropertyChanged
+ {
+ private System.Windows.Media.SolidColorBrush _connectionColor;
+
+ public string Protocol { get; set; }
+ public string LocalAddress { get; set; }
+ public int LocalPort { get; set; }
+ public string RemoteAddress { get; set; }
+ public int RemotePort { get; set; }
+ public string State { get; set; }
+ public int ProcessId { get; set; }
+ public string ProcessName { get; set; }
+ public DateTime ConnectionTime { get; set; }
+ public DateTime FirstConnectionTime { get; set; }
+ public string ConnectionStatus { get; set; }
+ public TimeSpan ConnectionDuration => DateTime.Now - FirstConnectionTime;
+ public string FormattedConnectionDuration => ConnectionDuration.ToString(@"hh\:mm\:ss");
+
+ public System.Windows.Media.SolidColorBrush ConnectionColor
+ {
+ get { return _connectionColor; }
+ set
+ {
+ if (_connectionColor != value)
+ {
+ _connectionColor = value;
+ OnPropertyChanged(nameof(ConnectionColor));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
diff --git a/EonaCat.PortMonitor/MainWindow.xaml b/EonaCat.PortMonitor/MainWindow.xaml
index cf093bc..5ba8865 100644
--- a/EonaCat.PortMonitor/MainWindow.xaml
+++ b/EonaCat.PortMonitor/MainWindow.xaml
@@ -1,7 +1,7 @@
+ Title="EonaCat Port Monitor" Height="600" Width="1600" WindowStartupLocation="CenterScreen">
@@ -43,8 +43,13 @@
+
+
+
-
+
@@ -58,6 +63,11 @@
+
+
+
@@ -73,6 +83,11 @@
+
+
+
@@ -96,6 +111,7 @@
+
diff --git a/EonaCat.PortMonitor/MainWindow.xaml.cs b/EonaCat.PortMonitor/MainWindow.xaml.cs
index 4e18374..712d362 100644
--- a/EonaCat.PortMonitor/MainWindow.xaml.cs
+++ b/EonaCat.PortMonitor/MainWindow.xaml.cs
@@ -15,8 +15,8 @@ using System.Net.Http;
using System.Windows.Media;
using Application = System.Windows.Application;
using Brushes = System.Drawing.Brushes;
-using Brush = System.Drawing.Brush;
using System.Windows.Threading;
+using Color = System.Drawing.Color;
namespace EonaCat.PortMonitor
{
@@ -189,7 +189,7 @@ namespace EonaCat.PortMonitor
System.Media.SystemSounds.Asterisk.Play();
var detailsWindow = new ConnectionDetailsWindow(conn);
- detailsWindow.Show();
+ detailsWindow.ShowDialog();
}
private void DataGrid_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
@@ -235,103 +235,156 @@ namespace EonaCat.PortMonitor
private async void MonitorConnections(object state)
{
- // Store the currently selected connection before the update
- ConnectionInfo selectedConnection = null;
-
- // Store the selected item from the DataGrid
- Dispatcher.Invoke(new Action(() =>
+ try
{
- selectedConnection = NetworkDataGrid.SelectedItem as ConnectionInfo;
- }));
+ ConnectionInfo selectedConnection = null;
- var currentConnections = await Task.Run(() => GetActiveConnections());
- var inboundConnections = currentConnections.Where(c => IsInboundConnection(c)).ToList();
- var outboundConnections = currentConnections.Where(c => IsOutboundConnection(c)).ToList();
- int totalConnections = currentConnections.Count;
-
- // Compare and update connections with the existing ones
- var newConnections = currentConnections.Where(c => !_previousConnections.Any(p => p.LocalAddress == c.LocalAddress && p.LocalPort == c.LocalPort)).ToList();
- var closedConnections = _previousConnections.Where(p => !currentConnections.Any(c => c.LocalAddress == p.LocalAddress && c.LocalPort == p.LocalPort)).ToList();
- var stateChangedConnections = currentConnections.Where(c => _previousConnections.Any(p => p.LocalAddress == c.LocalAddress && p.LocalPort == c.LocalPort && p.State != c.State)).ToList();
-
- // Add new connections or update existing ones
- foreach (var newConn in newConnections)
- {
- newConn.ConnectionStatus = "New";
- if (newConn.FirstConnectionTime == DateTime.MinValue)
+ // Store the currently selected connection
+ Dispatcher.Invoke(() =>
{
- newConn.FirstConnectionTime = DateTime.Now;
- }
+ selectedConnection = NetworkDataGrid.SelectedItem as ConnectionInfo;
+ });
- // Add the new connection to the collection
- Dispatcher.Invoke(() => Connections.Add(newConn));
- await NotifyNewConnectionAsync(newConn);
- }
+ var currentConnections = await Task.Run(GetActiveConnections);
- // Handle closed connections
- foreach (var closedConn in closedConnections)
- {
- var conn = Connections.FirstOrDefault(c => c.LocalAddress == closedConn.LocalAddress && c.LocalPort == closedConn.LocalPort);
- if (conn != null)
+ var inboundConnections = currentConnections.Where(IsInboundConnection).ToList();
+ var outboundConnections = currentConnections.Where(IsOutboundConnection).ToList();
+ int totalConnections = currentConnections.Count;
+
+ // Identify new connections
+ var newConnections = currentConnections
+ .Where(c => !_previousConnections.Any(p => p.LocalAddress == c.LocalAddress && p.LocalPort == c.LocalPort))
+ .ToList();
+
+ // Identify closed connections
+ var closedConnections = _previousConnections
+ .Where(p => !currentConnections.Any(c => c.LocalAddress == p.LocalAddress && c.LocalPort == p.LocalPort))
+ .ToList();
+
+ // Identify state-changed connections
+ var stateChangedConnections = currentConnections
+ .Where(c => _previousConnections.Any(p =>
+ p.LocalAddress == c.LocalAddress &&
+ p.LocalPort == c.LocalPort &&
+ p.State != c.State))
+ .ToList();
+
+ await Dispatcher.InvokeAsync(() =>
{
- conn.ConnectionStatus = "Closed";
-
- // Remove the connection if the status was set to closed for more than 5 seconds
- if (conn.ConnectionDuration.TotalSeconds > 5)
+ foreach (var newConn in newConnections)
{
- await Dispatcher.InvokeAsync(() => Connections.Remove(conn));
+ var existingConn = Connections.FirstOrDefault(c => c.LocalAddress == newConn.LocalAddress && c.LocalPort == newConn.LocalPort);
+ if (existingConn == null)
+ {
+ if (newConn.FirstConnectionTime == DateTime.MinValue)
+ newConn.FirstConnectionTime = DateTime.Now;
+
+ newConn.ConnectionStatus = "New";
+ newConn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.LightGreen)); // Softer green for new connections
+ Connections.Add(newConn);
+ }
+ else
+ {
+ existingConn.ConnectionStatus = "Updated";
+ existingConn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.LightGreen)); // Softer green for updated connections
+ }
}
- }
- }
- // Handle state changes
- foreach (var stateChangedConn in stateChangedConnections)
- {
- var conn = Connections.FirstOrDefault(c => c.LocalAddress == stateChangedConn.LocalAddress && c.LocalPort == stateChangedConn.LocalPort);
- if (conn != null)
- {
- conn.ConnectionStatus = "State Changed";
- conn.BackgroundColor = Brushes.Yellow;
-
- var timer = new DispatcherTimer
+ foreach (var closedConn in closedConnections)
{
- Interval = TimeSpan.FromSeconds(1)
- };
- timer.Tick += (sender, args) =>
+ var conn = Connections.FirstOrDefault(c => c.LocalAddress == closedConn.LocalAddress && c.LocalPort == closedConn.LocalPort);
+ if (conn != null)
+ {
+ conn.ConnectionStatus = "Closed";
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Gray)); // Softer gray for closed connections
+
+ Task.Delay(2000).ContinueWith(_ =>
+ {
+ Dispatcher.Invoke(() => Connections.Remove(conn));
+ });
+ }
+ }
+
+ foreach (var stateChangedConn in stateChangedConnections)
{
- conn.BackgroundColor = Brushes.Transparent;
- timer.Stop();
- };
- timer.Start();
- }
- }
+ var conn = Connections.FirstOrDefault(c => c.LocalAddress == stateChangedConn.LocalAddress && c.LocalPort == stateChangedConn.LocalPort);
+ if (conn != null)
+ {
+ conn.ConnectionStatus = "State Changed";
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Yellow)); // Softer yellow for state changes
- await Dispatcher.InvokeAsync(() =>
- {
- InboundDataGrid.ItemsSource = Connections.Where(x => IsInboundConnection(x));
- OutboundDataGrid.ItemsSource = Connections.Where(x => IsOutboundConnection(x));
+ var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
+ timer.Tick += (sender, args) =>
+ {
+ conn.ConnectionColor = new SolidColorBrush(Colors.Transparent);
+ timer.Stop();
+ };
+ timer.Start();
+ }
+ }
- NetworkDataGrid.Items.Refresh();
- FilterConnections_KeyUp(null, null);
- UpdateConnectionStats(totalConnections, inboundConnections.Count, outboundConnections.Count);
- });
-
- // Re-select the previously selected item after the refresh
- if (selectedConnection != null)
- {
- var selectedItem = Connections.FirstOrDefault(c => c.LocalAddress == selectedConnection.LocalAddress && c.LocalPort == selectedConnection.LocalPort);
- if (selectedItem != null)
- {
- Dispatcher.Invoke(() =>
+ // Apply colors based on connection state with softer variants
+ foreach (var conn in Connections)
{
- // Set the previously selected item back to the DataGrid
- NetworkDataGrid.SelectedItem = selectedItem;
- });
- }
- }
+ switch (conn.State)
+ {
+ case "IDLE":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Red)); // Softer red
+ break;
+ case "LISTENING":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Blue)); // Softer blue
+ break;
+ case "SYN_SENT":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Orange)); // Softer orange
+ break;
+ case "SYN_RECEIVED":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Purple)); // Softer purple
+ break;
+ case "ESTABLISHED":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.DarkGreen)); // Softer dark green
+ break;
+ case "CLOSE_WAIT":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.Brown)); // Softer brown
+ break;
+ case "TIME_WAIT":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.DarkGray)); // Softer dark gray
+ break;
+ case "FIN_WAIT_1":
+ case "FIN_WAIT_2":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.LightYellow)); // Softer light yellow
+ break;
+ case "LAST_ACK":
+ conn.ConnectionColor = new SolidColorBrush(AdjustColorBrightness(Colors.DarkOrange)); // Softer dark orange
+ break;
+ default:
+ conn.ConnectionColor = new SolidColorBrush(Colors.Transparent); // Default (no color)
+ break;
+ }
+ }
- // Update the previousConnections list for the next iteration
- _previousConnections = currentConnections;
+ // Update DataGrids
+ InboundDataGrid.ItemsSource = Connections.Where(IsInboundConnection).ToList();
+ OutboundDataGrid.ItemsSource = Connections.Where(IsOutboundConnection).ToList();
+ NetworkDataGrid.ItemsSource = Connections;
+
+ FilterConnections_KeyUp(null, null);
+ UpdateConnectionStats(totalConnections, inboundConnections.Count, outboundConnections.Count);
+ });
+ }
+ catch (Exception ex)
+ {
+ // Handle any exceptions appropriately
+ Console.WriteLine($"Error monitoring connections: {ex.Message}");
+ }
+ }
+
+ // Method to adjust the color brightness and make it softer
+ private System.Windows.Media.Color AdjustColorBrightness(System.Windows.Media.Color color)
+ {
+ byte r = (byte)(color.R + (255 - color.R) * 0.5); // Lighten the red component
+ byte g = (byte)(color.G + (255 - color.G) * 0.5); // Lighten the green component
+ byte b = (byte)(color.B + (255 - color.B) * 0.5); // Lighten the blue component
+ return System.Windows.Media.Color.FromArgb(180, r, g, b); // alpha = 180 for a softer color
}
private void UpdateConnectionStats(int total, int inbound, int outbound)
@@ -465,9 +518,6 @@ namespace EonaCat.PortMonitor
}
}
-
-
-
private void FilterConnections_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
FilterConnections_KeyUp(sender, null);
@@ -610,59 +660,40 @@ namespace EonaCat.PortMonitor
}
// Retrieve current background color
- SolidColorBrush currentBg = (SolidColorBrush)Application.Current.Resources["DynamicBackgroundColor"];
+ System.Windows.Media.SolidColorBrush currentBg = (System.Windows.Media.SolidColorBrush)Application.Current.Resources["DynamicBackgroundColor"];
- if (currentBg.Color == Colors.Black) // Dark Mode → Light Mode
+ if (currentBg.Color == System.Windows.Media.Colors.Black) // Dark Mode → Light Mode
{
- Application.Current.Resources["DynamicBackgroundColor"] = new SolidColorBrush(Colors.White);
- Application.Current.Resources["DynamicTextColor"] = new SolidColorBrush(Colors.Black);
+ Application.Current.Resources["DynamicBackgroundColor"] = new System.Windows.Media.SolidColorBrush(Colors.White);
+ Application.Current.Resources["DynamicTextColor"] = new System.Windows.Media.SolidColorBrush(Colors.Black);
btnTheme.Content = "🌙"; // Set icon to moon for dark mode
}
else // Light Mode → Dark Mode
{
- Application.Current.Resources["DynamicBackgroundColor"] = new SolidColorBrush(Colors.Black);
- Application.Current.Resources["DynamicTextColor"] = new SolidColorBrush(Colors.White);
+ Application.Current.Resources["DynamicBackgroundColor"] = new System.Windows.Media.SolidColorBrush(Colors.Black);
+ Application.Current.Resources["DynamicTextColor"] = new System.Windows.Media.SolidColorBrush(Colors.White);
btnTheme.Content = "🌞"; // Set icon to sun for light mode
}
}
- }
- public class ConnectionInfo : INotifyPropertyChanged
- {
- private Brush _backgroundColor;
-
- public string Protocol { get; set; }
- public string LocalAddress { get; set; }
- public int LocalPort { get; set; }
- public string RemoteAddress { get; set; }
- public int RemotePort { get; set; }
- public string State { get; set; }
- public int ProcessId { get; set; }
- public string ProcessName { get; set; }
- public DateTime ConnectionTime { get; set; }
- public DateTime FirstConnectionTime { get; set; }
- public string ConnectionStatus { get; set; }
- public TimeSpan ConnectionDuration => DateTime.Now - FirstConnectionTime;
- public string FormattedConnectionDuration => ConnectionDuration.ToString(@"hh\:mm\:ss");
-
- public Brush BackgroundColor
+ private void ProcessPathButton_Click(object sender, RoutedEventArgs e)
{
- get { return _backgroundColor; }
- set
+ // Check if an item is selected in the DataGrid
+ if (NetworkDataGrid.SelectedItem is ConnectionInfo selectedConnection)
{
- if (_backgroundColor != value)
+ try
{
- _backgroundColor = value;
- OnPropertyChanged(nameof(BackgroundColor));
+ var process = Process.GetProcessById(selectedConnection.ProcessId);
+ if (process != null && process.MainModule != null)
+ {
+ Process.Start("explorer.exe", $"/select, \"{process.MainModule.FileName}\"");
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Failed to get process path: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
}
}