Другие соображения < /strong> < /p>
Данные в Enumdisplaydevices, к сожалению, не содержат ничего уникального для определенного дисплея, поэтому не могут быть использованы для их использования. Данные в WindowmanagementObject (root \ wmi »,« select * from wmimonitorId) также не статический и изменения, за исключением серийного номера дисплеев, который, по -видимому, является единственной частью информации, которая может однозначно идентифицировать подключенный дисплей, даже если у вас есть несколько идентичных дисплеев. Подключен к серийному номеру), к DeviceId из EnumDisplayDevice, которые должны иметь общие данные, но никогда не появляются.
Код: Выделить всё
public class DisplayTracker
{
private static readonly Guid GUID_DEVCLASS_MONITOR = new Guid("4d36e96e-e325-11ce-bfc1-08002be10318");
static void Main(string[] args)
{
PrintDisplayNumbersAndSerials();
}
[StructLayout(LayoutKind.Sequential)]
private struct SP_DEVINFO_DATA
{
public int cbSize;
public Guid ClassGuid;
public uint DevInst;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct DISPLAY_DEVICE
{
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceString;
public int StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceKey;
}
[DllImport("SetupAPI.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid,
IntPtr Enumerator,
IntPtr hwndParent,
uint Flags
);
[DllImport("SetupAPI.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInfo(
IntPtr DeviceInfoSet,
uint MemberIndex,
ref SP_DEVINFO_DATA DeviceInfoData
);
[DllImport("SetupAPI.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool SetupDiGetDeviceInstanceId(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
int DeviceInstanceIdSize,
out int RequiredSize
);
[DllImport("SetupAPI.dll", SetLastError = true)]
private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);
private const uint DIGCF_PRESENT = 0x00000002;
public static void PrintDisplayNumbersAndSerials()
{
var serials = GetMonitorSerialsFromWMI();
var displays = GetCurrentDisplays();
var connectedDevices = GetConnectedDeviceInstanceIDs();
foreach (var kvp in serials)
{
string instanceName = kvp.Key;
string serial = kvp.Value;
string matchedDeviceInstance = connectedDevices.FirstOrDefault(dev => dev.Contains(instanceName, StringComparison.OrdinalIgnoreCase));
if (matchedDeviceInstance != null)
{
var match = displays.FirstOrDefault(d => matchedDeviceInstance.Contains(d.Key, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(match.Value))
{
Console.WriteLine($"Display Serial: {serial} -> Display Number: {match.Value}");
}
else
{
Console.WriteLine($"Display Serial: {serial} -> Display Number: (Not Found)");
}
}
else
{
Console.WriteLine($"Display Serial: {serial} -> Display Number: (Not Connected)");
}
}
}
public static Dictionary GetCurrentDisplays()
{
var displays = new Dictionary();
DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
displayDevice.cb = Marshal.SizeOf(displayDevice);
uint deviceIndex = 0;
while (EnumDisplayDevices(null, deviceIndex, ref displayDevice, 0))
{
displays[displayDevice.DeviceID] = displayDevice.DeviceName;
deviceIndex++;
}
return displays;
}
public static Dictionary GetMonitorSerialsFromWMI()
{
var monitorSerials = new Dictionary();
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT * FROM WmiMonitorID");
foreach (ManagementObject mo in searcher.Get())
{
string instanceName = mo["InstanceName"] as string;
string serial = GetStringFromUShortArray((ushort[])mo["SerialNumberID"]);
if (!string.IsNullOrEmpty(instanceName) && !string.IsNullOrEmpty(serial))
{
monitorSerials[instanceName] = serial;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error querying WMI: {ex.Message}");
}
return monitorSerials;
}
private static string GetStringFromUShortArray(ushort[] data)
{
if (data == null) return null;
return Encoding.ASCII.GetString(Array.ConvertAll(data, Convert.ToByte)).TrimEnd('\0');
}
public static List GetConnectedDeviceInstanceIDs()
{
var deviceInstanceIDs = new List();
Guid monitorGuid = GUID_DEVCLASS_MONITOR;
IntPtr deviceInfoSet = SetupDiGetClassDevs(ref monitorGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT);
if (deviceInfoSet == IntPtr.Zero) return deviceInstanceIDs;
try
{
SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
deviceInfoData.cbSize = Marshal.SizeOf(deviceInfoData);
uint index = 0;
while (SetupDiEnumDeviceInfo(deviceInfoSet, index, ref deviceInfoData))
{
StringBuilder deviceInstanceId = new StringBuilder(256);
int requiredSize;
if (SetupDiGetDeviceInstanceId(deviceInfoSet, ref deviceInfoData, deviceInstanceId, deviceInstanceId.Capacity, out requiredSize))
{
deviceInstanceIDs.Add(deviceInstanceId.ToString());
}
index++;
}
}
finally
{
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
return deviceInstanceIDs;
}
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... onnections