Frage

Für meine aktuellen C ++ Projekt Ich brauche eine eindeutige Zeichenfolge für jeden Monitor zu erkennen, die aktiv und auf einer großen Anzahl von Computern verbunden ist.

Die Forschung hat auf zwei Optionen hingewiesen

  1. Verwenden Sie WMI und die Win32_DesktopMonitor für alle aktiven Monitore abfragen. Verwenden Sie die PNPDeviceID zur eindeutigen Identifizierung von Monitoren.

  2. Mit der EnumDisplayDevices API, und graben, um die Geräte-ID zu erhalten.

Ich interessiere mich für die Geräte-ID zur eindeutigen Identifizierung Modell verwenden, da Monitore den Standard Plug & Play-Treiber wird eine generische Zeichenfolge als Monitornamen berichtet „Standard-Plug-and-Play-Monitor“

Ich habe Probleme mit der WMI-Methode auftreten, so scheint es, nur 1 Monitor auf meinem Vista-Rechner zu zurückkehren, an der doco sucht es stellt sich heraus, dass es nicht wie erwartet auf nicht WDDM-Geräten funktioniert.

Die EnumDisplayDevices scheint ein wenig problematisch, in Gang zu bringen, wenn es von einem Hintergrunddienst (vor allem auf Vista) läuft, wenn es in Sitzung 0 ist wird es keine Informationen zurück.

  • Hat jemand anderes hatte etwas ähnliches zu tun (einzigartiges Modell Zeichenfolge für alle angeschlossenen aktiven Monitore finden?)

  • Was Ansatz am besten funktioniert?

War es hilfreich?

Lösung

Dies ist meine aktuelle Arbeit-in-progress-Code für den Monitor Geräte-ID zu erfassen, zuverlässig.

CString DeviceID;
DISPLAY_DEVICE dd; 
dd.cb = sizeof(dd); 
DWORD dev = 0; 
// device index 
int id = 1; 
// monitor number, as used by Display Properties > Settings

while (EnumDisplayDevices(0, dev, &dd, 0))
{
    DISPLAY_DEVICE ddMon;
    ZeroMemory(&ddMon, sizeof(ddMon));
    ddMon.cb = sizeof(ddMon);
    DWORD devMon = 0;

    while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0))
    {
        if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE && 
                     !(ddMon.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
        {
            DeviceID.Format (L"%s", ddMon.DeviceID);
            DeviceID = DeviceID.Mid (8, DeviceID.Find (L"\\", 9) - 8);
        }
        devMon++;

        ZeroMemory(&ddMon, sizeof(ddMon));
        ddMon.cb = sizeof(ddMon);
    }

    ZeroMemory(&dd, sizeof(dd));
    dd.cb = sizeof(dd);
    dev++; 
}

Andere Tipps

Ich habe gerade entdeckt man Win32_PnPEntity für Service = „Monitor“ abfragen können, und es werden alle Monitore zurück.

Ergebnisse auf meinem Rechner:

select * from Win32_PnPEntity where service="monitor"

Availability | Caption               | ClassGuid                              | CompatibleID | ConfigManagerErrorCode | ConfigManagerUserConfig | CreationClassName | Description           | DeviceID                           | ErrorCleared | ErrorDescription | HardwareID  | InstallDate | LastErrorCode | Manufacturer | Name                  | PNPDeviceID                        | PowerManagementCapabilities | PowerManagementSupported | Service | Status | StatusInfo | SystemCreationClassName | SystemName
             | Dell 2007FP (Digital) | {4d36e96e-e325-11ce-bfc1-08002be10318} | array[0..0]  | 0                      | False                   | Win32_PnPEntity   | Dell 2007FP (Digital) | DISPLAY\DELA021\5&4F61016&0&UID257 |              |                  | array[0..0] |             |               | Dell Inc.    | Dell 2007FP (Digital) | DISPLAY\DELA021\5&4F61016&0&UID257 |                             |                          | monitor | OK     |            | Win32_ComputerSystem    | 8HVS05J
             | Dell ST2320L_Digital  | {4d36e96e-e325-11ce-bfc1-08002be10318} | array[0..0]  | 0                      | False                   | Win32_PnPEntity   | Dell ST2320L_Digital  | DISPLAY\DELF023\5&4F61016&0&UID256 |              |                  | array[0..0] |             |               | Dell Inc.    | Dell ST2320L_Digital  | DISPLAY\DELF023\5&4F61016&0&UID256 |                             |                          | monitor | OK     |            | Win32_ComputerSystem    | 8HVS05J

Wir haben mit EnumDisplayDevices um liebäugeln zu erkennen, ob die aktuellen Grafikkartenhersteller NVIDIA. Es ist nicht das gleiche, aber vielleicht würde es helfen. Unser Stück sah wie folgt aus:

int disp_num = 0;
    BOOL res = TRUE;
    do {
        DISPLAY_DEVICE disp_dev_info; 
        ZeroMemory( &disp_dev_info, sizeof(DISPLAY_DEVICE) );
        disp_dev_info.cb = sizeof(DISPLAY_DEVICE);
        res = EnumDisplayDevices( 0, disp_num++, &disp_dev_info, 0x00000001 );
        if(res &&
           disp_dev_info.DeviceString[0]!=0 && disp_dev_info.DeviceString[0]=='N' &&
           disp_dev_info.DeviceString[1]!=0 && disp_dev_info.DeviceString[1]=='V' && 
           disp_dev_info.DeviceString[2]!=0 && disp_dev_info.DeviceString[2]=='I' && 
           disp_dev_info.DeviceString[3]!=0 && disp_dev_info.DeviceString[3]=='D' && 
           disp_dev_info.DeviceString[4]!=0 && disp_dev_info.DeviceString[4]=='I' && 
           disp_dev_info.DeviceString[5]!=0 && disp_dev_info.DeviceString[5]=='A'){
            isNVidia = true;
        }
        int x = 0;
    }while( res != FALSE );

Pretty stumm, aber arbeiten.

Ich habe nie versucht, es von einem Dienst zu tun, aber EnumDisplayDevices im Allgemeinen gut funktioniert, wenn sie als Benutzer ausgeführt. Ich glaube, dass die Dienstleistungen in einem separaten Lauf (und ohne Kopf) Sitzung, die das Problem erklären könnte man dort zu sehen.

Könnten Sie ein Hilfsprogramm von Ihrem Dienst ausgeführt wird, ein Benutzerkonto Identitätswechsel, der den Zugriff auf die Displays hat?

Die Win32_DesktopMonitor Methode gibt nur 1 Monitor auf meinem Vista-Rechner als auch. Die PnP-ID scheint richtig eingestellt werden, though.

Ich habe ein schnelles Spiel mit der EnumDisplayDevices API habe, und während es zuverlässig die Adapter Details zu entdecken scheint (vermutlich, weil die meisten Menschen nicht verlassen, es als „Standard VGA“ für lange), es gibt nur „Plug and Play Monitor“für die angeschlossenen Monitore.

Dies spiegelt Forschung, die ich in diesen Jahren habe vor (hatte einen Code, um gemeinsam in Bestäuben diese Erinnerungen aus zu unterstützen).

Dies ist von einem normalen Benutzerkonto. Wenn Sie eine zuverlässige Art und Weise zu bekommen EnumDisplayDevices haben die PnP-ID, auch in normalen Benutzersitzungen zurückzukehren, würde ich interessiert sein - wir untersuchen derzeit, ob eine dieser Informationen zu einem Gerätetreiber verfügbar ist

Eine Sache, die Sie tun können, wenn Sie den Code aus Session # läuft 0 nicht zuverlässig genug ist, ist zu sehen, wenn Sie einen Helfer Prozess erzeugen kann (entweder mit CreateProcessAsUser oder mit Aktivierung Moniker mit COM) das wird in der Flucht Benutzerkontext.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top