【问题标题】:Monitor ID and Serial Number显示器 ID 和序列号
【发布时间】:2011-11-08 09:20:55
【问题描述】:

在 Windows 中,我们有关于 Monnitros 的信息 - 一些唯一的名称和 ID。例如

  1. 宏碁xxx
  2. 三星 xxx

我对如何在 C# 中获取信息有疑问,因为我知道我们可以从 WMI 获得序列号: root\WMI -> WmiMonitorID

关于显示器: root/CIMV2 Win32_DesktopMonitor

但我必须将这些信息放在一起,这意味着 Aceer S/N xxx 在 Windows 中具有 id 1

有人知道吗?

【问题讨论】:

    标签: c# system


    【解决方案1】:

    试一试:

    using System.Management;
    
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DesktopMonitor");     
    foreach (ManagementObject obj in searcher.Get())
        Console.WriteLine("Description: {0}", obj ["Description"]);
    

    编辑

    这是一个漂亮的类的链接,它将检索监视器的详细信息:

    http://wmimonitor.svn.sourceforge.net/viewvc/wmimonitor/DisplayInfoWMIProvider/WMIProvider/WMIProvider.cs?view=markup

    这是与上述链接关联的类。它应该为您提供有关显示器所需的一切:

    //DisplayInfoWMIProvider (c) 2009 by Roger Zander
    
    using System;
    using System.Collections;
    using System.Management.Instrumentation;
    using System.DirectoryServices;
    using System.Management;
    //using System.Security.Principal;
    using Microsoft.Win32;
    using System.Text;
    
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;            
    
    [assembly: WmiConfiguration(@"root\cimv2", HostingModel = ManagementHostingModel.LocalSystem)]
    namespace DisplayInfoWMIProvider
    {
        [System.ComponentModel.RunInstaller(true)]
        public class MyInstall : DefaultManagementInstaller
        {
            public override void Install(IDictionary stateSaver)
            {
                base.Install(stateSaver);
                System.Runtime.InteropServices.RegistrationServices RS = new System.Runtime.InteropServices.RegistrationServices();
    
                //This should be fixed with .NET 3.5 SP1
                //RS.RegisterAssembly(System.Reflection.Assembly.LoadFile(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\Reference Assemblies\Microsoft\Framework\v3.5\System.Management.Instrumentation.dll")), System.Runtime.InteropServices.AssemblyRegistrationFlags.SetCodeBase);
            }
    
            public override void Uninstall(IDictionary savedState)
            {
    
                try
                {
                    ManagementClass MC = new ManagementClass(@"root\cimv2:Win32_MonitorDetails");
                    MC.Delete();
                }
                catch { }
    
                try
                {
                    base.Uninstall(savedState);
                }
                catch { }
            }
        }
    
        [ManagementEntity(Name = "Win32_MonitorDetails")]
        public class DisplayDetails
        {
            [ManagementKey]
            public string PnPID { get; set; }
    
            [ManagementProbe]
            public string SerialNumber { get; set; }
    
            [ManagementProbe]
            public string Model { get; set; }
    
            [ManagementProbe]
            public string MonitorID { get; set; }
    
            /// <summary>
            /// The Constructor to create a new instances of the DisplayDetails class...
            /// </summary>
            public DisplayDetails(string sPnPID, string sSerialNumber, string sModel, string sMonitorID)
            {
                PnPID = sPnPID;
                SerialNumber = sSerialNumber;
                Model = sModel;
                MonitorID = sMonitorID;
            }
    
            /// <summary>
            /// This Function returns all Monitor Details
            /// </summary>
            /// <returns></returns>
            [ManagementEnumerator]
            static public IEnumerable GetMonitorDetails()
            {
                //Open the Display Reg-Key
                RegistryKey Display = Registry.LocalMachine;
                Boolean bFailed = false;
                try
                {
                    Display = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Enum\DISPLAY");
                }
                catch
                {
                    bFailed = true;
                }
    
                if (!bFailed & (Display != null))
                {
    
                    //Get all MonitorIDss
                    foreach (string sMonitorID in Display.GetSubKeyNames())
                    {
                        RegistryKey MonitorID = Display.OpenSubKey(sMonitorID);
    
                        if (MonitorID != null)
                        {
                            //Get all Plug&Play ID's
                            foreach (string sPNPID in MonitorID.GetSubKeyNames())
                            {
                                RegistryKey PnPID = MonitorID.OpenSubKey(sPNPID);
                                if (PnPID != null)
                                {
                                    string[] sSubkeys = PnPID.GetSubKeyNames();
    
                                    //Check if Monitor is active
                                    if (sSubkeys.Contains("Control"))
                                    {
                                        if (sSubkeys.Contains("Device Parameters"))
                                        {
                                            RegistryKey DevParam = PnPID.OpenSubKey("Device Parameters");
                                            string sSerial = "";
                                            string sModel = "";
    
                                            //Define Search Keys
                                            string sSerFind = new string(new char[] { (char)00, (char)00, (char)00, (char)0xff });
                                            string sModFind = new string(new char[] { (char)00, (char)00, (char)00, (char)0xfc });
    
                                            //Get the EDID code
                                            byte[] bObj = DevParam.GetValue("EDID", null) as byte[];
                                            if (bObj != null)
                                            {
                                                //Get the 4 Vesa descriptor blocks
                                                string[] sDescriptor = new string[4];
                                                sDescriptor[0] = Encoding.Default.GetString(bObj, 0x36, 18);
                                                sDescriptor[1] = Encoding.Default.GetString(bObj, 0x48, 18);
                                                sDescriptor[2] = Encoding.Default.GetString(bObj, 0x5A, 18);
                                                sDescriptor[3] = Encoding.Default.GetString(bObj, 0x6C, 18);
    
                                                //Search the Keys
                                                foreach (string sDesc in sDescriptor)
                                                {
                                                    if (sDesc.Contains(sSerFind))
                                                    {
                                                        sSerial = sDesc.Substring(4).Replace("\0", "").Trim();
                                                    }
                                                    if (sDesc.Contains(sModFind))
                                                    {
                                                        sModel = sDesc.Substring(4).Replace("\0", "").Trim();
                                                    }
                                                }
    
    
                                            }
                                            if (!string.IsNullOrEmpty(sPNPID + sSerFind + sModel + sMonitorID))
                                            {
                                                yield return new DisplayDetails(sPNPID, sSerial, sModel, sMonitorID);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 感谢回复,不幸的是描述不是唯一的名称,因为我有这种结果(我有两个监视器):默认监视器,默认监视器,通用 PnP 监视器
    • 此链接中的代码提供了有关 SerialNumber 和其他详细信息的信息,但没有告诉我 Windows 中监视器的顺序是什么:第一个监视器,第二个...
    • @jeremmy:你不必使用描述。将其替换为您想要的任何字段 - 序列号等。另外,请参阅带有课程链接的编辑答案。
    • 是的,我知道我有关于 SerialNumber 的信息,但不幸的是我们不知道监视器的 ID。例如。我们有 2 台显示器,序列号 S/N:A,S/N:B,使用上面的代码我有这个信息,但我不知道 S/N:A 是第一台显示器还是第二台显示器(SYSTEM\CurrentControlSet 中的顺序\Enum\DISPLAY 与 Windows 中的命令不同)。但也许我理解错了?
    • @jeremmy:您尝试过第二种解决方案吗?我在更新的答案中发布的课程?有没有办法从这个类中检索你需要的信息?
    【解决方案2】:

    root/CIMV2/Win32_DesktopMonitor/PnPDeviceID 仅显示我的 5 台显示器中的 2 台 和 root/WMI/WMIMonitorId/InstanceName 显示我的所有 5 台显示器

    strComputer = "." 
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\WMI") 
    Set colItems = objWMIService.ExecQuery( _
        "SELECT * FROM WmiMonitorID",,48) 
    For Each objItem in colItems 
        Wscript.Echo "-----------------------------------"
        Wscript.Echo "WmiMonitorID instance"
        Wscript.Echo "-----------------------------------"
        Wscript.Echo "InstanceName: " & objItem.InstanceName
    Next
    

    【讨论】:

    • 对我来说也一样:Win32_DesktopMonitor 显示 2,WMIMonitorId 显示 5。
    【解决方案3】:

    作为示例,我们使用它来使用 WMI 从主 HDD 检索序列:

    var search = new ManagementObjectSearcher("select * from Win32_LogicalDisk where DeviceID = 'C:'");
    var serials = search.Get().OfType<ManagementObject>();
    m_clientToken = serials.ElementAt(0)["VolumeSerialNumber"].ToString();
    

    也许您可以利用它来获取您的监视器信息,因为您知道要搜索哪个管理对象。您基本上使用 SQL 来检索您要查找的内容。

    【讨论】:

    • 感谢您的回复。我知道如何获取序列号信息,但问题是如何获取此信息:我们有 3 个监视器:S/N:xxx,S/N:yyy,S/N:zzz,我想现在是什么此监视器的 id,在 Windows 中哪个监视器是第一个,第二个...
    【解决方案4】:

    在我看来 root/CIMV2/Win32_DesktopMonitor/PnPDeviceID (1) 和 root/WMI/WMIMonitorId/InstanceName (2) 差不多 em> 相同

    我使用WMI Explorer在我的电脑上找到了以下内容

    (1) 显示\HWP2868\5&3EB7FBC&0&UID16777472

    (2) 显示\HWP2868\5&3eb7fbc&0&UID16777472_0

    有两个区别:(2) 末尾的 _0 和 (2) 的部分是小写的事实。

    目前我没有多个显示器可供参考,因此我无法为您提供更准确的方法来关联这两个条目。但在我看来,您可以编写两个查询,修改其中一个的搜索条件以匹配另一个的格式。但是您需要调查是否有可靠的模式来执行此操作。

    无论如何,如果不是通过查询,似乎有足够的通用元素能够在代码中进行匹配。

    【讨论】:

    • 奇怪的是,我有两台显示器,但在 root/CIMV2/Win32_DesktopMonitor 中我只填写了第二台显示器的 PnPDeviceID。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多