Monitor ID and Serial Number
In Windows we have information about our Monitros - some unique name and id. e.g.
- Acer xxx
- Samsung xxx
I have qeuestion how to get the information in C#, because I know that ser开发者_StackOverflowial number we can get from WMI: root\WMI -> WmiMonitorID
and about displays: root/CIMV2 Win32_DesktopMonitor
But I have to have this infromation together, it meens Aceer S/N xxx have id 1 in Windows
Have anybody some idea?
Give this a shot:
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"]);
EDIT:
And here's a link to a nice looking class that will retrieve the monitor details:
http://wmimonitor.svn.sourceforge.net/viewvc/wmimonitor/DisplayInfoWMIProvider/WMIProvider/WMIProvider.cs?view=markup
Here is the class associated with the above link. It should give you everything you need about the monitor:
//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);
}
}
}
}
}
}
}
}
}
}
}
root/CIMV2/Win32_DesktopMonitor/PnPDeviceID only show 2 of my 5 monitors and root/WMI/WMIMonitorId/InstanceName shows all 5 of my monitors
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
As an example, we use this to retrieve the serial from the primary HDD using WMI:
var search = new ManagementObjectSearcher("select * from Win32_LogicalDisk where DeviceID = 'C:'");
var serials = search.Get().OfType<ManagementObject>();
m_clientToken = serials.ElementAt(0)["VolumeSerialNumber"].ToString();
Perhaps you can utilize this to get your monitor information since you know which Mgmt Object to search. You basically use SQL to retrieve what you're looking for.
It seems to me that root/CIMV2/Win32_DesktopMonitor/PnPDeviceID (1) and root/WMI/WMIMonitorId/InstanceName (2) are nearly identical
I found the following on my computer using WMI Explorer
(1) DISPLAY\HWP2868\5&3EB7FBC&0&UID16777472
(2) DISPLAY\HWP2868\5&3eb7fbc&0&UID16777472_0
There are two differences: the _0 at the end of (2) and the fact that parts of (2) is lower case.
I do not have more than a single monitor for reference at the moment, therefore I can not provide you with a more accurate way to associate the two entries. But it looks to me like you could write two queries, modifying the search condition in one of them to match the other's format. But you need to investigate whether or not there is a reliable pattern to do so.
At any rate, there seems to be enough common elements to be able to make a match in code, if not by query.
精彩评论