Уникальное отслеживание мониторов в окнах через переподключенияC#

Место общения программистов C#
Anonymous
Уникальное отслеживание мониторов в окнах через переподключения

Сообщение Anonymous »

Я пишу программное обеспечение в C#, которое должно быть в состоянии однозначно отслеживать мониторы в Windows через переподключения. Он должен быть в состоянии заново открыть номер дисплея мониторов (например, Display1, Display2) при переподписании, чтобы передать его в изменение shipiSplaySettingSex, что, к сожалению, работает только с показателями дисплеев, полученных с использованием enumDisplayDevices. Моя первая мысль заключалась в том, чтобы запросить объект управления Windows (at: root \ wmi »,« select * from wmimonitorid) и получить серийный номер мониторов плюс часть информации, которая эквивалентна в EnumDisplayDevices, затем поиск EnumDisplayDevices с этой ключевой информацией, чтобы найти показатель, который соответствует сохранению, отображается, что выясняется, и это обеспечивает очень сложный, а также вывод, и это является очень сложным. Никакой общей информации нет. Я провел опрос CHATGPT по данным, которые они могут иметь общего, которые я могу соответствовать, однако каждое предложение не удалось. Я предполагаю, что есть способ сопоставить их, так как настройки дисплея Windows имеют всю эту информацию (серийный номер, номер отображения и т. Д.), Содержится в его пользовательском интерфейсе. Короче говоря, я хотел бы постоянно сохранить дисплей для моего программного обеспечения, чтобы его можно было распознавать и изменить в следующий раз, когда пользователь подключается. < /P>
Другие соображения < /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

Вернуться в «C#»