-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathDeviceManager.cs
More file actions
76 lines (69 loc) · 2.25 KB
/
DeviceManager.cs
File metadata and controls
76 lines (69 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using BytecodeApi.Extensions;
using BytecodeApi.Wmi;
using Microsoft.Win32;
using System.Collections.ObjectModel;
namespace BytecodeApi.Win32.SystemInfo;
/// <summary>
/// Provides a snapshot of all devices as shown in the Windows Device Manager.
/// </summary>
public sealed class DeviceManager
{
/// <summary>
/// Gets all <see cref="DeviceInfo" /> objects, categorized by device types.
/// </summary>
public ReadOnlyCollection<DeviceTypeInfo> DeviceTypes { get; }
private DeviceManager(IEnumerable<DeviceTypeInfo> deviceTypes)
{
DeviceTypes = deviceTypes.ToReadOnlyCollection();
}
/// <summary>
/// Creates a new <see cref="DeviceManager" /> instance and loads information about devices.
/// </summary>
/// <returns>
/// The <see cref="DeviceManager" /> this method creates.
/// </returns>
public static DeviceManager Create()
{
return new
(
WmiContext.Root
.GetNamespace("CIMV2")
.GetClass("Win32_PnPentity")
.ToArray()
.Where(obj => obj.Properties.FirstOrDefault(p => p.Name == "ClassGuid").Value is string)
.Select(obj => new DeviceInfo
(
obj.Properties
.Where(property => property.Value != null)
.ToDictionary(property => property.Name.Trim(), property => property.Value!)
))
.ToArray()
.GroupBy(device => (string)device.Attributes["ClassGuid"])
.Select(group =>
{
using RegistryKey? key = Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Control\Class\{group.Key}");
string? iconPath = key?.GetStringArrayValue("IconPath")?.FirstOrDefault();
int? iconIndex = null;
if (iconPath?.Contains(',') == true)
{
iconIndex = iconPath.SubstringFromLast(',').ToInt32OrNull();
if (iconIndex < 0)
{
iconIndex = -iconIndex;
}
iconPath = Environment.ExpandEnvironmentVariables(iconPath.SubstringUntilLast(','));
}
return new DeviceTypeInfo
{
ClassGuid = group.Key,
ClassName = key?.GetStringValue("Class").ToNullIfEmpty(),
IconPath = iconPath,
IconIndex = iconIndex,
Devices = group.OrderBy(device => device.Name).ToReadOnlyCollection()
};
})
.OrderBy(deviceType => deviceType.ClassName)
.ToArray()
);
}
}