2017-07-27 3 views
0

Für mein Programm muss ich detaillierte Informationen über die aktuellen Anzeigen erhalten. In meiner Forschung stieß ich auf this Post mit Gesprächen über die System.Windows.Forms.Screen-Klasse und seine EDID-Informationen zu verknüpfen. Zuerst habe ich versucht, den gefundenen Code mit p/invoke zu kopieren und einzufügen, um alle benötigten nativen Methoden und Strukturen zu liefern, aber es hat nicht funktioniert und mir nur eine Zeichenfolge von? für die InstanceID. Stattdessen habe ich versucht, die MSDN-Ressourcen zu verwenden und p/invoke erneut aufzurufen, um den Code selbst zu erstellen. Das ist, was ich kam mit:Verwenden von Setup Api zum Aufzählen von Monitoren pnp Geräte-IDs

private static void Foo() 
{ 
    Guid DisplayGUID = new Guid(Bar.GUID_DEVINTERFACE_MONITOR); 

    IntPtr DisplaysHandle = Bar.SetupDiGetClassDevs(ref DisplayGUID, null, IntPtr.Zero, (uint)(Win32.DIGCF_PRESENT | Win32.DIGCF_DEVICEINTERFACE)); 

    Bar.SP_DEVICE_INTERFACE_DATA Data = new Bar.SP_DEVICE_INTERFACE_DATA(); 
    Data.cbSize = Marshal.SizeOf(Data); 

    for (uint id = 0; Bar.SetupDiEnumDeviceInterfaces(DisplaysHandle, IntPtr.Zero, ref DisplayGUID, id, ref Data); id++) 
    { 
     Bar.SP_DEVINFO_DATA SPDID = new Bar.SP_DEVINFO_DATA(); 
     SPDID.cbSize = (uint)Marshal.SizeOf(SPDID); 

     Bar.SP_DEVICE_INTERFACE_DETAIL_DATA NDIDD = new Bar.SP_DEVICE_INTERFACE_DETAIL_DATA(); 

     if (IntPtr.Size == 8) //64 bit 
      NDIDD.cbSize = 8; 
     else //32 bit 
      NDIDD.cbSize = 4 + Marshal.SystemDefaultCharSize; 

     uint requiredsize = 0; 
     uint buffer = Bar.BUFFER_SIZE; 

     if (Bar.SetupDiGetDeviceInterfaceDetail(DisplaysHandle, ref Data, ref NDIDD, buffer, ref requiredsize, ref SPDID)) 
     { 
      uint size = 0; 
      Bar.CM_Get_Device_ID_Size(out size, SPDID.DevInst); 

      IntPtr ptrInstanceBuf = Marshal.AllocHGlobal((int)size); 

      Bar.CM_Get_Device_ID(SPDID.DevInst, ref ptrInstanceBuf, size); 

      string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf); 

      Console.WriteLine("InstanceID: {0}", InstanceID); 

      Marshal.FreeHGlobal(ptrInstanceBuf); 

      Console.WriteLine("DevicePath: {0}\n", NDIDD.DevicePath); 
     } 
    } 

    Bar.SetupDiDestroyDeviceInfoList(DisplaysHandle); 
} 

private class Bar 
{ 
    [DllImport("setupapi.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] string Enumerator, IntPtr hwndParent, uint Flags); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    public static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); 

    [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData); 

    [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, UInt32 deviceInterfaceDetailDataSize, ref UInt32 requiredSize, ref SP_DEVINFO_DATA deviceInfoData); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    public static extern int CM_Get_Device_ID_Size(out uint pulLen, UInt32 dnDevInst, int flags = 0); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    public static extern int CM_Get_Device_ID(uint dnDevInst, ref IntPtr Buffer, uint BufferLen, int ulFlags = 0); 

    public const int BUFFER_SIZE = 168; //guess 

    public const string GUID_DEVINTERFACE_MONITOR = "{E6F07B5F-EE97-4a90-B076-33F57BF4EAA7}"; 

    [Flags] 
    public enum DiGetClassFlags : uint 
    { 
     DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE 
     DIGCF_PRESENT = 0x00000002, 
     DIGCF_ALLCLASSES = 0x00000004, 
     DIGCF_PROFILE = 0x00000008, 
     DIGCF_DEVICEINTERFACE = 0x00000010, 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct SP_DEVICE_INTERFACE_DATA 
    { 
     public Int32 cbSize; 
     public Guid interfaceClassGuid; 
     public Int32 flags; 
     private UIntPtr reserved; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct SP_DEVINFO_DATA 
    { 
     public uint cbSize; 
     public Guid classGuid; 
     public uint DevInst; 
     public IntPtr reserved; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct SP_DEVICE_INTERFACE_DETAIL_DATA 
    { 
     public int cbSize; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] 
     public string DevicePath; 
    } 
} 

Mein Code kompiliert und ausgeführt, aber es gibt mir nicht den Ausgang ich suche.

Die Ausgabe, die ich suche ist:

InstanceID: DISPLAY\DELA00B\5&786e6ca&0&UID1048832 
DevicePath: \\?\display#dela00b#5&786e6ca&0&uid1048832#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} 

Aber das ist der Ausgang Ich erhalte:

InstanceID: l 
DevicePath: \\?\display#dela00b#5&786e6ca&0&uid1048832#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} 

Meine Frage kommt in Form von dem, was ist das Problem, das InstanceID verursacht nicht korrekt ausgeben.

Antwort

0

Es stellte sich heraus, dass ich die falsche p/invoke-Signatur verwendete. CM_Get_Device_ID sollte wie folgt aussehen:

[DllImport("setupapi.dll", SetLastError = true)] 
public static extern int CM_Get_Device_ID(uint dnDevInst, StringBuilder Buffer, int BufferLen, int ulFlags = 0); 

Auch Aktualisiert Usage Code:

StringBuilder IDBuffer = new StringBuilder((int)buffer); 
Bar.CM_Get_Device_ID(SPDID.DevInst, IDBuffer, (int)buffer); 

Console.WriteLine("InstanceID: {0}", IDBuffer.ToString()); 
Console.WriteLine("DevicePath: {0}\n", NDIDD.DevicePath); 
Verwandte Themen