Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use MMI instead of System.Management for dotnet core #25

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
25d025f
Add support for Linux.
shshzi Apr 14, 2020
6f18344
Tweak some of the OS-specific functionality.
MatthewKing Apr 19, 2020
64404ab
Add strong naming.
MatthewKing Apr 19, 2020
1909037
Update readme. Update copyright years.
MatthewKing Apr 19, 2020
d8f3c43
Add registry value extension method.
MatthewKing Apr 19, 2020
0c446e2
Add strong naming disclaimer.
MatthewKing Apr 19, 2020
41c1893
Make return values more consistent.
MatthewKing Apr 20, 2020
47c51af
Increment version number.
MatthewKing Apr 20, 2020
6062a17
Add support for system drive serial number on Linux.
progdogusmc Apr 23, 2020
7daa831
Add some tests for the Linux system drive serial number implementation.
MatthewKing Apr 26, 2020
efff9ca
Tweak JSON deserialization.
MatthewKing Apr 30, 2020
b36ca64
Increment version number.
MatthewKing Apr 30, 2020
ac3bcbd
Improve WmiDeviceIdComponent.
Zaczero Jun 17, 2020
7821364
Increment version number.
MatthewKing Jun 17, 2020
f2d090d
Clean up WMI usage and add some extra error handling.
MatthewKing Jun 24, 2020
d38a9a4
Add OSX support.
techtim Jul 6, 2020
8122ec0
Refactor.
MatthewKing Jul 9, 2020
bc5fc11
Update cross-platform support matrix for OSX.
MatthewKing Jul 9, 2020
7e0be70
Add missing brackets in readme.
Twistie Oct 2, 2020
17a9376
Add support for .NET 3.5.
MatthewKing Oct 25, 2020
c80b252
Move the IOPlatformSerialNumber logic to the OSInstallationID component.
MatthewKing Oct 25, 2020
d66152b
Update readme.
MatthewKing Oct 25, 2020
225ee51
Increment version number.
MatthewKing Oct 25, 2020
dd02768
Allow the delimiter to be specified.
MatthewKing Nov 4, 2020
abc4891
Add support for MMI (System.Management.Infrastructure) in dotnet core…
shshzi Feb 7, 2021
59cef46
Add support for MMI (System.Management.Infrastructure) in dotnet core…
shshzi Feb 7, 2021
228a832
Add MMI
shshzi Feb 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/DeviceId/Components/FileDeviceIdComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public string GetValue()
catch (UnauthorizedAccessException)
{
// Can fail if we have no permissions to access the file.
throw new DeviceIdComponentFailedToObtainValueException("Can't access file");
}
catch(Exception e)
{
throw new DeviceIdComponentFailedToObtainValueException("Failed reading file", e);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/DeviceId/Components/FileTokenDeviceIdComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ public string GetValue()
var value = Encoding.ASCII.GetString(bytes);
return value;
}
catch { }
catch(Exception e)
{
throw new DeviceIdComponentFailedToObtainValueException("Failed to read file contents", e);
}
}
else
{
Expand Down
77 changes: 36 additions & 41 deletions src/DeviceId/Components/NetworkAdapterDeviceIdComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;

namespace DeviceId.Components
Expand Down Expand Up @@ -61,15 +61,18 @@ public string GetValue()
// First attempt to retrieve the addresses using the CIMv2 interface.
values = GetMacAddressesUsingCimV2();
}
catch (ManagementException ex)
catch
{
// In case we are notified of an invalid namespace, attempt to lookup the adapters using WMI.
// In case we are notified of an exception (usually, invalid namespace), attempt to lookup the adapters using WMI.
// Could avoid this catch by manually checking for the CIMv2 namespace.

if (ex.ErrorCode == ManagementStatus.InvalidNamespace)
try
{
values = GetMacAddressesUsingWmi();
}
catch
{
// Can also fail (for example, some Windows 7 machines)
}
}
}

Expand All @@ -81,20 +84,18 @@ public string GetValue()
values = NetworkInterface.GetAllNetworkInterfaces()
.Where(x => !_excludeWireless || x.NetworkInterfaceType != NetworkInterfaceType.Wireless80211)
.Select(x => x.GetPhysicalAddress().ToString())
.Where(x => x != "000000000000")
.Where(x => x != "" && x != "000000000000")
.Select(x => FormatMacAddress(x))
.ToList();
}
catch
{

throw new DeviceIdComponentFailedToObtainValueException("Failed collecting network adapters");
}
}

if (values != null)
{
values.Sort();
}

return (values != null && values.Count > 0)
? string.Join(",", values.ToArray())
Expand All @@ -109,36 +110,29 @@ internal List<string> GetMacAddressesUsingWmi()
{
var values = new List<string>();

try
var adapters = WmiHelper.GetWMIInstances(@"root\cimv2", "Win32_NetworkAdapter", new string[] { "MACAddress", "PhysicalAdapter" });

foreach (var adapter in adapters)
{
using var managementObjectSearcher = new ManagementObjectSearcher("select MACAddress, PhysicalAdapter from Win32_NetworkAdapter");
using var managementObjectCollection = managementObjectSearcher.Get();
foreach (var managementObject in managementObjectCollection)
{
try
try
{
var isPhysical = Boolean.Parse(adapter["PhysicalAdapter"] as string);

if (_excludeNonPhysical && !isPhysical)
{
// Skip non physcial adapters if instructed to do so.
var isPhysical = (bool)managementObject["PhysicalAdapter"];
if (_excludeNonPhysical && !isPhysical)
{
continue;
}

var macAddress = (string)managementObject["MACAddress"];
if (!string.IsNullOrEmpty(macAddress))
{
values.Add(macAddress);
}
continue;
}
finally

var macAddress = adapter["MACAddress"] as string;
if (!string.IsNullOrEmpty(macAddress))
{
managementObject.Dispose();
values.Add(macAddress);
}
}
}
catch
{

catch
{
}
}

return values;
Expand All @@ -152,28 +146,29 @@ internal List<string> GetMacAddressesUsingCimV2()
{
var values = new List<string>();

using var managementClass = new ManagementClass("root/StandardCimv2", "MSFT_NetAdapter", new ObjectGetOptions { });
var adapters = WmiHelper.GetWMIInstances(@"root\StandardCimv2", "MSFT_NetAdapter", new string[] { "ConnectorPresent", "NdisPhysicalMedium", "PermanentAddress" });

foreach (var managementInstance in managementClass.GetInstances())
foreach (var adapter in adapters)
{
try
{
var isPhysical = Boolean.Parse(adapter["ConnectorPresent"] as string);
var ndisMedium = UInt32.Parse(adapter["NdisPhysicalMedium"] as string);

// Skip non physcial adapters if instructed to do so.
var isPhysical = (bool)managementInstance["ConnectorPresent"];
if (_excludeNonPhysical && !isPhysical)
{
continue;
}

// Skip wireless adapters if instructed to do so.
var ndisMedium = (uint)managementInstance["NdisPhysicalMedium"];
if (_excludeWireless && ndisMedium == 9) // Native802_11
{
continue;
}

// Add the MAC address to the list of values.
var value = managementInstance["PermanentAddress"] as string;
var value = adapter["PermanentAddress"] as string;
if (value != null)
{
// Ensure the hardware addresses are formatted as MAC addresses if possible.
Expand All @@ -182,9 +177,9 @@ internal List<string> GetMacAddressesUsingCimV2()
values.Add(value);
}
}
finally
catch
{
managementInstance.Dispose();

}
}

Expand Down
7 changes: 4 additions & 3 deletions src/DeviceId/Components/RegistryValueDeviceIdComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Win32;
using System;
using Microsoft.Win32;

namespace DeviceId.Components
{
Expand Down Expand Up @@ -46,9 +47,9 @@ public string GetValue()
var value = Registry.GetValue(_key, _valueName, null);
return value?.ToString();
}
catch
catch(Exception e)
{
return null;
throw new DeviceIdComponentFailedToObtainValueException(String.Format("Failed to read registry value ({0}\\{1})", _key, _valueName), e);
}
}
}
Expand Down
27 changes: 11 additions & 16 deletions src/DeviceId/Components/SystemDriveSerialNumberDeviceIdComponent.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using System.Management;
using System.Collections.Generic;

namespace DeviceId.Components
{
Expand All @@ -24,24 +24,19 @@ public SystemDriveSerialNumberDeviceIdComponent() { }
/// <returns>The component value.</returns>
public string GetValue()
{
var systemLogicalDiskDeviceId = Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 2);

var queryString = $"SELECT * FROM Win32_LogicalDisk where DeviceId = '{systemLogicalDiskDeviceId}'";
using var searcher = new ManagementObjectSearcher(queryString);
try
{
var systemLogicalDiskDeviceId = Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 2);

foreach (ManagementObject disk in searcher.Get())
var logicalDiskToPartition = Array.Find(WmiHelper.GetWMIInstances(@"root\cimv2", "Win32_LogicalDiskToPartition"), logicalDriveToPartition => (logicalDriveToPartition["Dependent"] as IDictionary<string, object>)["DeviceID"] as string == systemLogicalDiskDeviceId);
var partition = Array.Find(WmiHelper.GetWMIInstances(@"root\cimv2", "Win32_DiskDriveToDiskPartition"), partition => (partition["Dependent"] as IDictionary<string, object>)["DeviceID"] as string == (logicalDiskToPartition["Antecedent"] as IDictionary<string, object>)["DeviceID"] as string);
var diskdrive = Array.Find(WmiHelper.GetWMIInstances(@"root\cimv2", "Win32_DiskDrive "), diskDriveToPartition => diskDriveToPartition["DeviceID"] as string == (partition["Antecedent"] as IDictionary<string, object>)["DeviceID"] as string);
return diskdrive["SerialNumber"] as string;
}
catch(Exception e)
{
foreach (ManagementObject partition in disk.GetRelated("Win32_DiskPartition"))
{
foreach (ManagementObject drive in partition.GetRelated("Win32_DiskDrive"))
{
var serialNumber = drive["SerialNumber"] as string;
return serialNumber;
}
}
throw new DeviceIdComponentFailedToObtainValueException("Failed to GetValue() in SystemDriveSerialNumberDeviceIdComponent", e);
}

return null;
}
}
}
26 changes: 6 additions & 20 deletions src/DeviceId/Components/WmiDeviceIdComponent.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Management;

namespace DeviceId.Components
{
Expand Down Expand Up @@ -44,29 +43,16 @@ public string GetValue()
{
var values = new List<string>();

try
foreach (var obj in WmiHelper.GetWMIInstances(@"root\cimv2", _wmiClass))
{
using var managementObjectSearcher = new ManagementObjectSearcher($"SELECT {_wmiProperty} FROM {_wmiClass}");
using var managementObjectCollection = managementObjectSearcher.Get();
foreach (var managementObject in managementObjectCollection)
try
{
try
{
var value = managementObject[_wmiProperty] as string;
if (value != null)
{
values.Add(value);
}
}
finally
{
managementObject.Dispose();
}
values.Add(((IDictionary<string, object>)obj)[_wmiProperty].ToString());
}
}
catch
{
catch
{

}
}

values.Sort();
Expand Down
3 changes: 1 addition & 2 deletions src/DeviceId/DeviceId.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
<PackageReference Include="System.Management" Version="4.6.0" />
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="4.7.1" />
</ItemGroup>
Expand All @@ -44,5 +44,4 @@
<Visible>false</Visible>
</None>
</ItemGroup>

</Project>
46 changes: 46 additions & 0 deletions src/DeviceId/DeviceIdComponentFailedToObtainValueException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeviceId
{
class DeviceIdComponentFailedToObtainValueException : Exception
{
//
// Summary:
// Initializes a new instance of the DeviceIDComponentException class.
public DeviceIdComponentFailedToObtainValueException()
{

}

//
// Summary:
// Initializes a new instance of the DeviceIDComponentException class with a specified error
// message.
//
// Parameters:
// message:
// The message that describes the error.
public DeviceIdComponentFailedToObtainValueException(string message) : base(message)
{
}

//
// Summary:
// Initializes a new instance of the DeviceIDComponentException class with a specified error
// message and a reference to the inner exception that is the cause of this exception.
//
// Parameters:
// message:
// The error message that explains the reason for the exception.
//
// innerException:
// The exception that is the cause of the current exception, or a null reference
// (Nothing in Visual Basic) if no inner exception is specified.
public DeviceIdComponentFailedToObtainValueException(string message, Exception innerException): base(message, innerException)
{
}
}
}
14 changes: 13 additions & 1 deletion src/DeviceId/Formatters/HashDeviceIdFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,23 @@ public string GetDeviceId(IEnumerable<IDeviceIdComponent> components)
throw new ArgumentNullException(nameof(components));
}

var value = string.Join(",", components.OrderBy(x => x.Name).Select(x => x.GetValue()).ToArray());
var value = string.Join(",", components.OrderBy(x => x.Name).Select(x => GetValue(x)).ToArray());
var bytes = Encoding.UTF8.GetBytes(value);
using var algorithm = _hashAlgorithm.Invoke();
var hash = algorithm.ComputeHash(bytes);
return _byteArrayEncoder.Encode(hash);
}

private string GetValue(IDeviceIdComponent component)
{
try
{
return component.GetValue();
}
catch(DeviceIdComponentFailedToObtainValueException)
{
return "";
}
}
}
}
14 changes: 13 additions & 1 deletion src/DeviceId/Formatters/StringDeviceIdFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,19 @@ public string GetDeviceId(IEnumerable<IDeviceIdComponent> components)
throw new ArgumentNullException(nameof(components));
}

return string.Join(_delimiter, components.OrderBy(x => x.Name).Select(x => _encoder.Encode(x)).ToArray());
return string.Join(_delimiter, components.OrderBy(x => x.Name).Select(x => GetValue(x)).ToArray());
}

private string GetValue(IDeviceIdComponent component)
{
try
{
return _encoder.Encode(component);
}
catch (DeviceIdComponentFailedToObtainValueException)
{
return "";
}
}
}
}
Loading