- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在开发一个应用程序,它将在相应显示器的对话框中显示从 EDID block (显示器型号、ID、S/N 等)派生的信息。
This code用于查找显示器的 EDID 信息。它通过枚举HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\[Monitor]\[PnPID]\Device Parameters\EDID下的DISPLAY键来提取EDID信息。
更新:以上代码依赖于 PnP 使用注册表的“副作用”。我现在正在使用 SetupAPI枚举监视器,它可以正确处理附加/移除的监视器(与上面链接中的代码不同。)
我正在尝试将 Windows.Forms.Screen.AllScreens[](\\.\DISPLAY1、\\.\DISPLAY2 等)中的每个屏幕与从上述注册表检查返回的条目相关联。
注意:在下面的代码块中,DisplayDetails.GetMonitorDetails() 现在已使用 SetupAPI 替换为更强大的注册表枚举代码,但返回的数据是相同的。
例如
private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Polling displays on {0}:", System.Environment.MachineName);
int i = 0;
foreach ( DisplayDetails dd in DisplayDetails.GetMonitorDetails())
{
Console.WriteLine( "Info: Model: {0}, MonitorID: {1}, PnPID: {2}, Serial#:{3}", dd.Model, dd.MonitorID, dd.PnPID, dd.SerialNumber );
Console.WriteLine( "Does this correlate to Screen: {0}?", Screen.AllScreens[i++].DeviceName );
}
}
信息:型号:DELL P2411H,显示器 ID:DELA06E,PnPID:5&2e2fefea&0&UID1078018,序列号:F8NDP0C...PU
这与 Screen:\\.\DISPLAY1 相关吗?
信息:型号:DELL P2411H,显示器 ID:DELA06E,PnPID:5&2e2fefea&0&UID1078019,序列号:F8NDP0C...AU
这与 Screen:\\.\DISPLAY2 相关吗?
回答:否
在测试中,我发现它们之间没有可靠的关联(我有一个系统,其中第一个枚举的显示是\\.\DISPLAY2)。
我的问题:有没有办法可靠地获取给定 Forms.Screen 的 EDID 信息?我可以获取 EDID block ,但找不到将其关联到 UI 的路径顶级表格。提示用户是不可取的,因为在我的用例中,两个(或更多)显示器可能具有相同的型号和分辨率,并且在 S/N 中仅相差几位数字。
我一直在寻找遵循 Forms.Screen API、Win32 EnumDisplay、其他注册表 GUID(PnP 和驱动程序相关)的路径,但没有找到任何有希望的路径。
我还研究了 WMI Win32_DesktopMonitor API (Windows 7),但是它似乎没有任何更多信息可以帮助我将它与 Windows.Forms.Screen.AllScreens[] 条目相关联。
我怀疑是否有办法做到这一点,它是通过 SetupAPI,但我还没有找到它。
最佳答案
将 GDI 解析为 SetupAPI 的方法在 EnumDisplayDevices 中可用。应用程序接口(interface)。如果您为 dwFlags 传入 EDD_GET_DEVICE_INTERFACE_NAME,监视器枚举将返回以下形式的 DeviceID 信息:
Monitor 0 info:
DeviceName: \\.\DISPLAY1
MonitorInfo: Dell P2411H(Digital)
DeviceID: \\?\DISPLAY#DELA06E#5&2e2fefea&0&UID1078018#{e6f07b5f-ee97-4a90-b076-3
3f57bf4eaa7}
Monitor 1 info:
DeviceName: \\.\DISPLAY2
MonitorInfo: Dell P2411H(Digital)
DeviceID: \\?\DISPLAY#DELA06E#5&2e2fefea&0&UID1078019#{e6f07b5f-ee97-4a90-b076-3
3f57bf4eaa7}
DeviceID 字段现在与 didd.DevicePath 的结果相匹配,如以下 C# 片段中检索的那样:
Guid MonitorGUID = new Guid(Win32.GUID_DEVINTERFACE_MONITOR);
// We start at the "root" of the device tree and look for all
// devices that match the interface GUID of a monitor
IntPtr h = Win32.SetupDiGetClassDevs(ref MonitorGUID, IntPtr.Zero, IntPtr.Zero, (uint)(Win32.DIGCF_PRESENT | Win32.DIGCF_DEVICEINTERFACE));
if (h.ToInt64() != Win32.INVALID_HANDLE_VALUE)
{
bool Success = true;
uint i = 0;
while (Success)
{
// create a Device Interface Data structure
Win32.SP_DEVICE_INTERFACE_DATA dia = new Win32.SP_DEVICE_INTERFACE_DATA();
dia.cbSize = (uint)Marshal.SizeOf(dia);
// start the enumeration
Success = Win32.SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref MonitorGUID, i, ref dia);
if (Success)
{
// build a DevInfo Data structure
Win32.SP_DEVINFO_DATA da = new Win32.SP_DEVINFO_DATA();
da.cbSize = (uint)Marshal.SizeOf(da);
// build a Device Interface Detail Data structure
Win32.SP_DEVICE_INTERFACE_DETAIL_DATA didd = new Win32.SP_DEVICE_INTERFACE_DETAIL_DATA();
didd.cbSize = (uint)(4 + Marshal.SystemDefaultCharSize); // trust me :)
// now we can get some more detailed information
uint nRequiredSize = 0;
uint nBytes = Win32.BUFFER_SIZE;
if (Win32.SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, out nRequiredSize, ref da))
{
// Now we get the InstanceID
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal((int)nBytes);
Win32.CM_Get_Device_ID(da.DevInst, ptrInstanceBuf, (int)nBytes, 0);
string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf);
Console.WriteLine("InstanceID: {0}", InstanceID );
Marshal.FreeHGlobal(ptrInstanceBuf);
Console.WriteLine("DevicePath: {0}", didd.DevicePath );
}
i++;
}
}
}
Win32.SetupDiDestroyDeviceInfoList(h);
}
示例输出:
InstanceID: DISPLAY\DELA06E\5&2E2FEFEA&0&UID1078018
DevicePath: \\?\display#dela06e#5&2e2fefea&0&uid1078018#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
原始 EnumDisplayDevices 中的 DeviceName 与 Forms.Screen.DeviceName 属性匹配。
有了这两条信息,现在可以在 SetupDIEnumDeviceInterface 遍历期间使用如下片段读取 EDID block :
private static byte[] GetMonitorEDID(IntPtr pDevInfoSet, SP_DEVINFO_DATA deviceInfoData)
{
IntPtr hDeviceRegistryKey = SetupDiOpenDevRegKey(pDevInfoSet, ref deviceInfoData,
DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
if (hDeviceRegistryKey == IntPtr.Zero)
{
throw new Exception("Failed to open a registry key for device-specific configuration information");
}
IntPtr ptrBuff = Marshal.AllocHGlobal((int)256);
try
{
RegistryValueKind lpRegKeyType = RegistryValueKind.Binary;
int length = 256;
uint result = RegQueryValueEx(hDeviceRegistryKey, "EDID", 0, ref lpRegKeyType, ptrBuff, ref length);
if (result != 0)
{
throw new Exception("Can not read registry value EDID for device " + deviceInfoData.ClassGuid);
}
}
finally
{
RegCloseKey(hDeviceRegistryKey);
}
byte[] edidBlock = new byte[256];
Marshal.Copy(ptrBuff, edidBlock, 0, 256);
Marshal.FreeHGlobal(ptrBuff);
return edidBlock;
}
最后,可以针对 VESA 描述符 block 进行解析,如 DisplayDetails.GetMonitorDetails() method in this code. 中所示
关于windows - 寻找 Forms.Screen.DeviceName 的可靠映射以监控 EDID 信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10237937/
我正在尝试运行以下内容:: Press to see code - name: Snapshot BI nodes hosts: [CLUSTER-BI,CLUSTER-BI-REPL
在这里尝试心理重置:我尝试使用 MSMQ 创建一个可靠、持久的堆栈,但没有成功 所以更一般地说: 我有生产者(一个 web 服务,虽然“只有一个”,但也是多线程的)/消费者(多个进程,根据需要设置)。
试图为分布式系统找到一个商业日志框架。此框架必须允许远程服务器上的 .NET 应用程序记录可以在中央位置收集的消息。如果可能,中央位置应将消息存储在 SQL Server 数据库中。 要求: 能够在远
我正在开发 Restful 服务,我们将在数据库中插入/更新新记录。 由于REST使用HTTP进行通信,而HTTP并不可靠,我担心如果连接失败,请求可能无法发送到服务器。 我在 link 中找到的建议
我正在尝试实现一个页面,员工可以在其中登录并添加、修改、更新工作案例。 我有一个选择列表,其中包含从数据库加载的数据(员工姓名)。在这个数据库中,我有基本信息、用户名、ID、密码、电子邮件。 选择列表
我在 C 代码和 Python 代码之间(偶尔)得到略有不同的计算结果,并设法找到了一个例子。在 Python 中,我得到了这个: >>> print "%.55f" %\ ... (-2.49999
例如如果我将计时器设置为每天午夜到期,如果一个“失火”(例如,由于服务器关闭而不会触发回调)会发生什么?我在文档中找不到它。 有没有办法让这个定时器在服务器重启时立即触发回调? PS:我了解 Quar
我有一组不同长度的非零序列,我正在使用 Keras LSTM 对这些序列建模。我使用 Keras Tokenizer 进行分词(分词从 1 开始)。为了使序列具有相同的长度,我使用了填充。 填充示例:
我遇到了一个非常有趣的可靠 session 行为。我正在使用 netTcp 绑定(bind) + 双工 channel + 可靠 session 。 当我尝试在 channel.faulted 上收听
问题: 给定表 table_a 和 table_b,每当 table_a 更新时,我都需要可靠地(并发地)执行这样的操作: SELECT table_a 中的一些行。 在应用程序代码中计算一些内容。
我们目前的设计 环境 Redis 2.8.17 我们已经实现了我们的可靠队列,使用类似于 redis 文档中描述的模式的模式,在 RPOPLPUSH 下 但是,考虑到其阻塞性质,我们正在使用 BRPO
在我们的 WCF 应用程序中,我正在尝试配置可靠的 session 。 服务: 客户:
我使用这个 Delphi 7 代码来检测 Internet Explorer 是否正在运行: function IERunning: Boolean; begin Result := FindWi
我正在准备构建一个应用程序,该应用程序能够向 GPS 设备发送/接收航路点。通过一些谷歌搜索,我发现了很多可能对此目的有用的库: Java Chaeron GPS GPSLib4J Python Py
我有几个关于 WCF 可靠 session 可靠性的问题: WCF 是否在重试期间重新序列化消息? 2。如果 1 是正确的 - 它是否在消息参数被处理后发生? 3. 如果 2 是正确的 - 是否有任何
对于使用 $(this)[0].defaultValue 来确定文本框值是否已从原始值发生变化的一些反馈,我将不胜感激,例如 //keyUp event if($(this)[0].defaultVa
我正在开发一个具有以下特征的实时应用程序: 数百个客户端将同时插入行/文档,每个客户端每隔几秒插入一行。 大部分仅追加;几乎所有的行/文档,一旦插入,就永远不会改变。 只有当数据刷新到磁盘时,客户端才
场景:最终用户(不受信任的)提供了一个字符串,例如 "Hello, {name}!" .在服务器上,我想以 my_string.format(name="Homer") 的形式对该用户提供的字符串进行
我在推送通知方面遇到一些问题。我们使用 Firebase 来推送通知。问题是我可以在一台 iPhone 上正确接收 PushNotifications,但无法在另一台 iPhone 上接收它们。我在
从 python 到 c++,这是我能得到的最接近 python 的装饰器。 这个解决方案感觉有点像 hack,因为在要装饰的函数之后运行的代码在 Timer 析构函数中是隐式调用的。不过它确实有效。
我是一名优秀的程序员,十分优秀!