我试图获取显示名称,因为它们出现在"屏幕分辨率"窗口(Win8.1 x64)。
首先我尝试了EnumDisplayDevices
var deviceInfo = new DISPLAY_DEVICEW();
uint i = 0;
while (true)
{
if (!NativeMethods.EnumDisplayDevices(null, i++, deviceInfo, 0))
{
break;
}
PrintDeviceInfo(deviceInfo);
NativeMethods.EnumDisplayDevices(deviceInfo.DeviceName, 0, deviceInfo, EDD_GET_DEVICE_INTERFACE_NAME);
PrintDeviceInfo(deviceInfo);
}
第二次调用EnumDisplayDevices
(带EDD_GET_DEVICE_INTERFACE_NAME
)确实产生了显示名称,因为它显示在我的主显示屏上(在DISPLAY_DEVICEW.DeviceString中)。但是对于我的HDMI连接电视,该字段包含通用PnP监视器,而不是 SAMSUNG ,因为它出现在"屏幕分辨率"窗口。也许它通过HDMI连接的事实在某种程度上是相关的?
然后我尝试了安装API
var hdevinfo = NativeMethods.SetupDiGetClassDevs(ref GUID_DEVINTERFACE_MONITOR, null, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hdevinfo == INVALID_HANDLE_VALUE) return;
var spDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
uint memberIndex = 0;
while (true)
{
bool success = NativeMethods.SetupDiEnumDeviceInterfaces(hdevinfo, null, ref GUID_DEVINTERFACE_MONITOR, memberIndex++, spDeviceInterfaceData);
if (!success)
{
break;
}
PrintInterfaceData(spDeviceInterfaceData);
uint requiredSize;
var devInfoData = new SP_DEVINFO_DATA();
NativeMethods.SetupDiGetDeviceInterfaceDetail(hdevinfo, spDeviceInterfaceData, IntPtr.Zero, 0, out requiredSize, devInfoData);
PrintDevInfoData(devInfoData);
var interfaceDetail = Marshal.AllocHGlobal((int)requiredSize);
var cbSize = (Marshal.SizeOf(typeof(uint)) + Marshal.SystemDefaultCharSize);
Marshal.WriteInt32(interfaceDetail, 0, cbSize);
NativeMethods.SetupDiGetDeviceInterfaceDetail(hdevinfo, spDeviceInterfaceData, interfaceDetail, requiredSize, IntPtr.Zero, null);
var dynamicType = GetDeviceInterfaceDetailDataType(requiredSize);
var interfaceDetailStruct = Marshal.PtrToStructure(interfaceDetail, dynamicType);
Marshal.FreeHGlobal(interfaceDetail);
PrintInterfaceDetail(interfaceDetailStruct);
uint propertyRegDataType;
NativeMethods.SetupDiGetDeviceRegistryProperty(hdevinfo, devInfoData, SPDRP_FRIENDLYNAME, out propertyRegDataType, null, 0, out requiredSize);
Console.WriteLine(Marshal.GetLastWin32Error());
}
查看来自不同方法的返回值,一切似乎都有效,但最后一次调用SetupDiGetDeviceRegistryProperty
失败了ERROR_INVALID_DATA
(也就是说,该方法返回false并且GetLastWin32Error
得到13
)。根据{{3}},这意味着设备不存在所请求的属性,或者属性数据无效。
我实际上循环了所有可能的SPDRP
值(0-24)并且它们都导致相同的失败。只是为了澄清,我希望方法失败,但是设置ERROR_INSUFFICIENT_BUFFER
并设置requiredSize
(后者只保留其先前的值,因为非托管代码不会更改它)。
这里是SetupDiGetDeviceRegistryProperty
的签名(所有其他方法按预期工作):
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
public uint cbSize = (uint) Marshal.SizeOf(typeof (SP_DEVINFO_DATA));
public Guid ClassGuid;
public uint DevInst;
public IntPtr Reserved;
}
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiGetDeviceRegistryProperty(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
uint property,
out uint propertyRegDataType,
byte[] propertyBuffer,
uint propertyBufferSize,
out uint requiredSize);
答案 0 :(得分:-1)
看起来我正在寻找的是impossible:
没有受支持的方式来计算您提到的ID 以编程方式。从来没有为设计目标提供方法 用于标记与屏幕具有相同ID的监视器的应用程序 分辨率控制面板使用