Skip to content

Commit 4b67d86

Browse files
committed
Feature: Copy context menu, fix wifi adpater network interace is null
1 parent 3c32bed commit 4b67d86

15 files changed

+633
-348
lines changed

Source/NETworkManager.Converters/WiFiChannelCenterFrequencyToChannelStringConvertert.cs renamed to Source/NETworkManager.Converters/WiFiChannelCenterFrequencyToChannelStringConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace NETworkManager.Converters;
77

8-
public sealed class WiFiChannelCenterFrequencyToChannelStringConvertert : IValueConverter
8+
public sealed class WiFiChannelCenterFrequencyToChannelStringConverter : IValueConverter
99
{
1010
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
1111
{

Source/NETworkManager.Converters/WiFiPhyKindToStringConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public sealed class WiFiPhyKindToStringConverter : IValueConverter
1010
{
1111
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
1212
{
13-
return value is not WiFiPhyKind phyKind ? "-/-" : $"{WiFi.GetHumandReadablePhyKind(phyKind)}";
13+
return value is not WiFiPhyKind phyKind ? "-/-" : $"{WiFi.GetHumanReadablePhyKind(phyKind)}";
1414
}
1515

1616
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/NETworkManager.Localization/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3655,4 +3655,7 @@ Try again in a few seconds.</value>
36553655
<data name="GroupViewName_General" xml:space="preserve">
36563656
<value>General</value>
36573657
</data>
3658+
<data name="BSSID" xml:space="preserve">
3659+
<value>BSSID</value>
3660+
</data>
36583661
</root>

Source/NETworkManager.Models/NETworkManager.Models.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<PackageReference Include="DnsClient" Version="1.7.0" />
3434
<PackageReference Include="IPNetwork2" Version="2.6.605" />
3535
<PackageReference Include="Lextm.SharpSnmpLib" Version="12.5.2" />
36+
<PackageReference Include="log4net" Version="2.0.15" />
3637
<PackageReference Include="MahApps.Metro" Version="2.4.10" />
3738
<PackageReference Include="MahApps.Metro.IconPacks.FontAwesome" Version="4.11.0" />
3839
<PackageReference Include="MahApps.Metro.IconPacks.Material" Version="4.11.0" />

Source/NETworkManager.Models/Network/WiFi.cs

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Collections.ObjectModel;
3+
using System.Diagnostics;
44
using System.Linq;
5-
using System.Management.Automation;
65
using System.Threading.Tasks;
76
using Windows.Devices.WiFi;
87
using Windows.Networking.Connectivity;
98
using Windows.Security.Credentials;
9+
using log4net;
1010

1111
//https://docs.microsoft.com/en-us/uwp/api/windows.devices.wifi.wifiadapter.requestaccessasync
1212
//var access = await WiFiAdapter.RequestAccessAsync() == WiFiAccessStatus.Allowed;
@@ -18,6 +18,8 @@ namespace NETworkManager.Models.Network;
1818
/// </summary>
1919
public static class WiFi
2020
{
21+
private static readonly ILog Log = LogManager.GetLogger(typeof(WiFi));
22+
2123
/// <summary>
2224
/// Get all WiFi adapters async with additional information from <see cref="NetworkInterface"/>.
2325
/// </summary>
@@ -26,29 +28,39 @@ public static async Task<List<WiFiAdapterInfo>> GetAdapterAsync()
2628
{
2729
List<WiFiAdapterInfo> wifiAdapterInfos = new();
2830

29-
IReadOnlyList<WiFiAdapter> wifiAdapters = await WiFiAdapter.FindAllAdaptersAsync();
31+
var wifiAdapters = await WiFiAdapter.FindAllAdaptersAsync();
3032

31-
if (wifiAdapters.Count > 0)
33+
if (wifiAdapters.Count <= 0)
34+
return wifiAdapterInfos;
35+
36+
var networkInterfaces = await NetworkInterface.GetNetworkInterfacesAsync();
37+
38+
foreach (var wiFiAdapter in wifiAdapters)
3239
{
33-
List<NetworkInterfaceInfo> networkInterfaces = await NetworkInterface.GetNetworkInterfacesAsync();
40+
var wiFiAdapterId = wiFiAdapter.NetworkAdapter.NetworkAdapterId.ToString();
41+
42+
var networkInterface = networkInterfaces.FirstOrDefault(x => x.Id.TrimStart('{').TrimEnd('}')
43+
.Equals(wiFiAdapterId, StringComparison.OrdinalIgnoreCase));
3444

35-
foreach (var wifiAdapter in wifiAdapters)
45+
if (networkInterface != null)
3646
{
37-
var networkInteraceInfo = networkInterfaces.FirstOrDefault(x => x.Id.TrimStart('{').TrimEnd('}').Equals(wifiAdapter.NetworkAdapter.NetworkAdapterId.ToString(), StringComparison.OrdinalIgnoreCase));
38-
3947
wifiAdapterInfos.Add(new WiFiAdapterInfo
4048
{
41-
NetworkInterfaceInfo = networkInteraceInfo,
42-
WiFiAdapter = wifiAdapter
49+
NetworkInterfaceInfo = networkInterface,
50+
WiFiAdapter = wiFiAdapter
4351
});
4452
}
53+
else
54+
{
55+
Log.Warn($"Could not find network interface for WiFi adapter with id: {wiFiAdapterId}");
56+
}
4557
}
4658

4759
return wifiAdapterInfos;
4860
}
4961

5062
/// <summary>
51-
/// Get all available WiFi networks for an adapter with additional informations.
63+
/// Get all available WiFi networks for an adapter with additional information's.
5264
/// </summary>
5365
/// <param name="adapter">WiFi adapter as <see cref="WiFiAdapter"/>.</param>
5466
/// <returns>A report as <see cref="WiFiNetworkScanInfo"/> including a list of <see cref="WiFiNetworkInfo"/>.</returns>
@@ -58,21 +70,16 @@ public static async Task<WiFiNetworkScanInfo> GetNetworksAsync(WiFiAdapter adapt
5870
await adapter.ScanAsync();
5971

6072
// Try to get the current connected wifi network of this network adapter
61-
var (ssid, bssid) = TryGetConnectedNetworkFromWiFiAdapter(adapter.NetworkAdapter.NetworkAdapterId.ToString());
73+
var (_, bssid) = TryGetConnectedNetworkFromWiFiAdapter(adapter.NetworkAdapter.NetworkAdapterId.ToString());
6274

63-
List<WiFiNetworkInfo> wifiNetworkInfos = new();
64-
65-
foreach (var availableNetwork in adapter.NetworkReport.AvailableNetworks)
75+
var wifiNetworkInfos = adapter.NetworkReport.AvailableNetworks.Select(availableNetwork => new WiFiNetworkInfo
6676
{
67-
wifiNetworkInfos.Add(new WiFiNetworkInfo()
68-
{
69-
AvailableNetwork = availableNetwork,
70-
IsHidden = string.IsNullOrEmpty(availableNetwork.Ssid),
71-
IsConnected = availableNetwork.Bssid.Equals(bssid, StringComparison.OrdinalIgnoreCase)
72-
});
73-
}
77+
AvailableNetwork = availableNetwork,
78+
IsHidden = string.IsNullOrEmpty(availableNetwork.Ssid),
79+
IsConnected = availableNetwork.Bssid.Equals(bssid, StringComparison.OrdinalIgnoreCase)
80+
}).ToList();
7481

75-
return new WiFiNetworkScanInfo()
82+
return new WiFiNetworkScanInfo
7683
{
7784
NetworkAdapterId = adapter.NetworkAdapter.NetworkAdapterId,
7885
WiFiNetworkInfos = wifiNetworkInfos,
@@ -90,16 +97,17 @@ public static async Task<WiFiNetworkScanInfo> GetNetworksAsync(WiFiAdapter adapt
9097
/// </summary>
9198
/// <param name="adapterId">GUID of the WiFi network adapter.</param>
9299
/// <returns>SSID and BSSID of the connected wifi network. Values are null if not detected.</returns>
100+
// ReSharper disable once UnusedTupleComponentInReturnValue
93101
private static (string SSID, string BSSID) TryGetConnectedNetworkFromWiFiAdapter(string adapterId)
94102
{
95103
string ssid = null;
96104
string bssid = null;
97105

98-
using (System.Management.Automation.PowerShell powerShell = System.Management.Automation.PowerShell.Create())
106+
using (var powerShell = System.Management.Automation.PowerShell.Create())
99107
{
100108
powerShell.AddScript("netsh wlan show interfaces");
101109

102-
Collection<PSObject> psOutputs = powerShell.Invoke();
110+
var psOutputs = powerShell.Invoke();
103111

104112
/*
105113
if (powerShell.Streams.Error.Count > 0) { // Handle error? }
@@ -115,29 +123,30 @@ private static (string SSID, string BSSID) TryGetConnectedNetworkFromWiFiAdapter
115123
* BSSID : 6a:d7:...
116124
*/
117125

118-
bool foundAdapter = false;
126+
var foundAdapter = false;
119127

120-
foreach (PSObject outputItem in psOutputs)
128+
foreach (var outputItem in psOutputs)
121129
{
122130
// Find line with the network adapter id...
123131
if (outputItem.ToString().Contains(adapterId, StringComparison.OrdinalIgnoreCase))
124132
foundAdapter = true;
125133

126-
if (foundAdapter)
127-
{
128-
// Extract SSID from the line
129-
if (outputItem.ToString().Contains(" SSID ", StringComparison.OrdinalIgnoreCase))
130-
ssid = outputItem.ToString().Split(':')[1].Trim();
131-
132-
// Extract BSSID from the line
133-
if (outputItem.ToString().Contains(" BSSID ", StringComparison.OrdinalIgnoreCase))
134-
bssid = outputItem.ToString().Split(':', 2)[1].Trim();
135-
136-
// Break if we got the values, otherwise we might overwrite them
137-
// with values from another adapter.
138-
if (!string.IsNullOrEmpty(ssid) && !string.IsNullOrEmpty(bssid))
139-
break;
140-
}
134+
// ...and skip all lines until we found it.
135+
if (!foundAdapter)
136+
continue;
137+
138+
// Extract SSID from the line
139+
if (outputItem.ToString().Contains(" SSID ", StringComparison.OrdinalIgnoreCase))
140+
ssid = outputItem.ToString().Split(':')[1].Trim();
141+
142+
// Extract BSSID from the line
143+
if (outputItem.ToString().Contains(" BSSID ", StringComparison.OrdinalIgnoreCase))
144+
bssid = outputItem.ToString().Split(':', 2)[1].Trim();
145+
146+
// Break if we got the values, otherwise we might overwrite them
147+
// with values from another adapter.
148+
if (!string.IsNullOrEmpty(ssid) && !string.IsNullOrEmpty(bssid))
149+
break;
141150
}
142151
}
143152

@@ -240,7 +249,7 @@ public static async Task<bool> IsWpsAvailable(WiFiAdapter adapter, WiFiAvailable
240249
/// <returns>WiFi channel like 3 or 48.</returns>
241250
public static int GetChannelFromChannelFrequency(int kilohertz)
242251
{
243-
return (double)ConvertChannelFrequencyToGigahertz(kilohertz) switch
252+
return ConvertChannelFrequencyToGigahertz(kilohertz) switch
244253
{
245254
// 2.4 GHz
246255
2.412 => 1,
@@ -305,7 +314,7 @@ public static bool Is2dot4GHzNetwork(int kilohertz)
305314
{
306315
var x = ConvertChannelFrequencyToGigahertz(kilohertz);
307316

308-
return x >= 2.412 && x <= 2.472;
317+
return x is >= 2.412 and <= 2.472;
309318
}
310319

311320
/// <summary>
@@ -317,14 +326,14 @@ public static bool Is5GHzNetwork(int kilohertz)
317326
{
318327
var x = ConvertChannelFrequencyToGigahertz(kilohertz);
319328

320-
return x >= 5.180 && x <= 5.825;
329+
return x is >= 5.180 and <= 5.825;
321330
}
322331

323332
/// <summary>
324333
/// Get the human readable network authentication type.
325334
/// </summary>
326335
/// <param name="networkAuthenticationType">WiFi network authentication type as <see cref="NetworkAuthenticationType"/>.</param>
327-
/// <returns>Human readable autentication type as string like "Open" or "WPA2 Enterprise".</returns>
336+
/// <returns>Human readable authentication type as string like "Open" or "WPA2 Enterprise".</returns>
328337
public static string GetHumanReadableNetworkAuthenticationType(NetworkAuthenticationType networkAuthenticationType)
329338
{
330339
return networkAuthenticationType switch
@@ -337,7 +346,7 @@ public static string GetHumanReadableNetworkAuthenticationType(NetworkAuthentica
337346
NetworkAuthenticationType.WpaPsk => "WPA PSK",
338347
NetworkAuthenticationType.SharedKey80211 => "WEP",
339348
NetworkAuthenticationType.Ihv => "IHV",
340-
NetworkAuthenticationType.Unknown => "Unkown",
349+
NetworkAuthenticationType.Unknown => "Unknown",
341350
NetworkAuthenticationType.None => "-/-",
342351
_ => "-/-",
343352
};
@@ -348,7 +357,7 @@ public static string GetHumanReadableNetworkAuthenticationType(NetworkAuthentica
348357
/// </summary>
349358
/// <param name="phyKind">WiFi network phy kind as <see cref="WiFiPhyKind"/>.</param>
350359
/// <returns>Human readable phy kind as string like "802.11g" or "802.11ax".</returns>
351-
public static string GetHumandReadablePhyKind(WiFiPhyKind phyKind)
360+
public static string GetHumanReadablePhyKind(WiFiPhyKind phyKind)
352361
{
353362
return phyKind switch
354363
{

Source/NETworkManager.Models/Network/WiFiNetworkInfo.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
namespace NETworkManager.Models.Network;
44

5-
65
/// <summary>
76
/// Class contains information about a WiFi network.
87
/// </summary>
98
public class WiFiNetworkInfo
109
{
1110
#region Variables
1211
/// <summary>
13-
/// Informations about an available WiFi network.
12+
/// Information's about an available WiFi network.
1413
/// </summary>
15-
public WiFiAvailableNetwork AvailableNetwork { get; set; }
14+
public WiFiAvailableNetwork AvailableNetwork { get; init; }
1615

1716
/// <summary>
1817
/// Indicates if the WiFi network Ssid is hidden.

Source/NETworkManager.Models/Network/WiFiNetworkScannfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ public class WiFiNetworkScanInfo
1717
/// <summary>
1818
/// List of available WiFi networks on the network adapter.
1919
/// </summary>
20-
public List<WiFiNetworkInfo> WiFiNetworkInfos { get; set; }
20+
public List<WiFiNetworkInfo> WiFiNetworkInfos { get; init; }
2121

2222
/// <summary>
2323
/// Timestamp when the scan was performed.
2424
/// </summary>
25-
public DateTime Timestamp { get; set; }
25+
public DateTime Timestamp { get; init; }
2626
#endregion
2727

2828
/// <summary>

Source/NETworkManager/MainWindow.xaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,14 @@
135135
<TextBlock Text="{x:Static localization:Strings.UnlockProfile}" Style="{StaticResource LinkTextBlock}" Margin="5,0" />
136136
</StackPanel>
137137
</Button>
138-
<ComboBox ItemsSource="{Binding ProfileFiles}" SelectedItem="{Binding SelectedProfileFile, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Background="{DynamicResource MahApps.Brushes.Gray8}" IsDropDownOpen="{Binding IsProfileFileDropDownOpened}" BorderThickness="0" MinWidth="100" HorizontalAlignment="Left" Margin="0,0,10,0">
138+
<ComboBox ItemsSource="{Binding ProfileFiles}"
139+
SelectedItem="{Binding SelectedProfileFile, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
140+
Background="{DynamicResource MahApps.Brushes.Gray8}"
141+
IsDropDownOpen="{Binding IsProfileFileDropDownOpened}"
142+
BorderThickness="0"
143+
MinWidth="100"
144+
HorizontalAlignment="Left"
145+
Margin="0,0,10,0">
139146
<ComboBox.ItemTemplate>
140147
<DataTemplate>
141148
<Grid>

0 commit comments

Comments
 (0)