WMI mal wieder (Win32_POTSModemToSerialPort)
-
Hallo,
Ich versuche gerade mir von WMI alle Modems an einem seriellen Port auflisten zu lassen.Dafür ist "Win32_POTSModemToSerialPort" scheinbar ideal. Jedoch gibt es bei dieser Klasse das Objekt "Win32_POTSModem ref Dependent;" welches auf das Modem weist.
Wie komm ich an die Daten dieses Modems ran? IWbemClassObject::Get() liefert mir den String "\\ACER-SEB\root\cimv2:Win32_POTSModem.DeviceID="PCI\\VEN_8086&DEV_24C6&SUBSYS_00641025&REV_03\\3&61AAA01&0&FE" zurück.
Wie komm ich jetzt an die Modem-Daten ran? Muss ich da dann ein extra Query starten also ("Select * FROM Win32_POTSModem WHERE DeviceID="...."") oder gibt es da eine einfachere Möglichkeit, also kann ich direkt daraus ein IWbemClassObject bekommen?
Als Basis für den Programmteil mit WMI diente http://www.codeproject.com/system/UsingWMI.asp .
-
Get erwartet doch als Argument den Namen der Eigenschaft, die du haben möchtest. Alternativ gibt es dort auch Methoden, um die einzelnen Eigenschaften des WMI-Objekts zu enumierieren.
-
das Problem ist: wie komm ich dann an mein IWbemClassObject-Pointer ran? Wenn ich Get aufrufe bekomm ich ja nur den obigen string in meinen Variant geschrieben aber wie komm ich von dem Variant wieder zu einem IWbemClassObject?
Mein Code sieht bisher so aus:
CComPtr< IWbemClassObject > processor; _variant_t var_val; [...] hr = processor->Get( L"Dependent", 0, &var_val, NULL, NULL ); if(SUCCEEDED(hr)) { _bstr_t str = var_val; std::cout << "Value: " << str << std::endl; }Wenn ich die Werte über BeginEnumeration und Next abhole habe ich das gleiche Problem.
-
Was ist denn die Variable "processor"?
EDIT: Ach so, hatte nicht richtig gelesen

Hast du mal probiert, Get als Typ CIM_OBJECT zu übergeben und zu schauen, ob du dann einen Zeiger auf das entsprechende Objekt erhältst und keine String-Repräsentation?
-
das ist ein Objekt von "Win32_POTSModemToSerialPort" und von dem will ich die Eigenschaft "dependent" und die soll ein Objekt von der WMI-Klasse "Win32_POTSModem" enthalten. Und von dem brauch ich letzendlich die Eigenschaft "Name".
Link zur Klasse Win32_POTSModemToSerialPort:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_potsmodemtoserialport.aspdas ist der komplette Code:
CComPtr< IEnumWbemClassObject > enumerator; hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_POTSModemToSerialPort", WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator ); if ( SUCCEEDED( hr ) ) { { // read the first instance from the enumeration (only one on single processor machines) CComPtr< IWbemClassObject > processor = NULL; ULONG retcnt; hr = enumerator->Next( WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &processor ), &retcnt ); if ( SUCCEEDED( hr ) ) { if ( retcnt > 0 ) { // we have a processor installed :) // now extract a property value _variant_t var_val; hr = processor->Get( L"Dependent", 0, &var_val, NULL, NULL ); //hr = processor->GetMethod( L"Dependent", 0, NULL, reinterpret_cast<IWbemClassObject**>( &modem)); if ( SUCCEEDED( hr ) ) { _bstr_t s[url]tr = var_val; std::cout << "Processor name: " << str << std::endl; } else // Jetzt kommt nur noch Fehlerbehandlung
-
masterofx32 schrieb:
Hast du mal probiert, Get als Typ CIM_OBJECT zu übergeben und zu schauen, ob du dann einen Zeiger auf das entsprechende Objekt erhältst und keine String-Repräsentation?
Geht das?
pvtType ist als "Out" definiert.....Edit:
Ich hab jetzt mal geschaut was da rauskommt also pvtType wird "CIM_REFERENCE". Also müsste es richtig sein... jetzt muss ich nur noch aus der komischen Reference ein C-Pointer bekommen....Edit die 2.:
der Variant ist allerdings vom Typ VT_BSTR.
-
UB909 schrieb:
masterofx32 schrieb:
Hast du mal probiert, Get als Typ CIM_OBJECT zu übergeben und zu schauen, ob du dann einen Zeiger auf das entsprechende Objekt erhältst und keine String-Repräsentation?
Geht das?
pvtType ist als "Out" definiert.....Ach so, ja dann nicht.
Was erhältst du denn wenn du den variant einem WBEmClassPointer zuweist? Naja, kann da im Moment auch nicht wirklich helfen. Hab zwar schon mit WMI gearbeitet aber bin noch nie solch einer Referenz gefolgt. Alles weitere wären also nur Mutmaßungen.
-
masterofx32 schrieb:
UB909 schrieb:
masterofx32 schrieb:
Hast du mal probiert, Get als Typ CIM_OBJECT zu übergeben und zu schauen, ob du dann einen Zeiger auf das entsprechende Objekt erhältst und keine String-Repräsentation?
Geht das?
pvtType ist als "Out" definiert.....Ach so, ja dann nicht.
Was erhältst du denn wenn du den variant einem WBEmClassPointer zuweist?zugriffsverletzung....
Naja, kann da im Moment auch nicht wirklich helfen. Hab zwar schon mit WMI gearbeitet aber bin noch nie solch einer Referenz gefolgt. Alles weitere wären also nur Mutmaßungen.

naja da weißt du immerhin noch deutlich mehr wie ich....
-
Hab mir die Methoden nochmal angeschaut. Wenn die Eigenschaft wirklich nur als String abrufbar ist, wäre vielleicht die Methode IWbemServices::GetObject sinnvoll, um die referenzierte Instanz zu erhalten. Damit musst du dann auch kein neues Query ausführen.
-
Ok so funktionierts.... Danke...
Ich werde den Code dann mal Posten wenn ich ihn ein bisschen übersichtlicher gemacht habe.
-
So und nun noch den Versprochenen Code (falls es jemand mal brauchen kann).
CComPtr< IWbemLocator > locator; hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast< void** >( &locator ) ); if ( FAILED( hr ) ) { std::cerr << "Instantiation of IWbemLocator failed" << std::endl; return -1; } CComPtr< IWbemLocator > locator; // connect to local service with current credentials CComPtr< IWbemServices > service; hr = locator->ConnectServer( L"root\\cimv2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &service ); if ( SUCCEEDED( hr ) ) { // execute a query CComPtr< IEnumWbemClassObject > enumerator; hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_POTSModemToSerialPort", WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator ); if ( SUCCEEDED( hr ) ) { // read the first instance from the enumeration (only one on single processor machines) IWbemClassObject *ModemToSerial = NULL; ULONG retcnt; // Get First ModemToSerialPort-Object hr = enumerator->Next(WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &ModemToSerial ), &retcnt ); // Enumerate the other Modems. while((SUCCEEDED(hr)) && (retcnt > 0)) { IWbemClassObject *Modem = NULL; IWbemClassObject *SerialPort = NULL; _variant_t varModemReference; _variant_t varSerialPortReference; std::wstring sModemName; std::wstring sSerialPort; // Get String to the Win32_POTSModem-Reference hr = ModemToSerial->Get(L"Dependent", 0, &varModemReference, NULL, NULL ); if(SUCCEEDED (hr)) { // Get Object of the String. hr = service->GetObject(varModemReference.bstrVal, 0, NULL, &Modem, NULL); if(SUCCEEDED (hr)) { _variant_t varModem; // Get the Name or the wanted Value of Win32_POTSModem. hr = Modem->Get(L"Name", 0, &varModem, NULL, NULL ); if(SUCCEEDED (hr)) { sModemName = varModem.bstrVal; } } } // Get String to the Win32_SerialPort-Reference hr = ModemToSerial->Get(L"Antecedent", 0, &varSerialPortReference, NULL, NULL ); if(SUCCEEDED (hr)) { // Get Object of the String. hr = service->GetObject(varSerialPortReference.bstrVal, 0, NULL, &SerialPort, NULL); if(SUCCEEDED (hr)) { _variant_t varSerialPort; // Get the Name or the wanted Value of Win32_POTSModem. hr = SerialPort->Get(L"DeviceID", 0, &varSerialPort, NULL, NULL ); if(SUCCEEDED (hr)) { sSerialPort = varSerialPort.bstrVal; } } } // Release Pointer SAFE_RELEASE(ModemToSerial); SAFE_RELEASE(SerialPort); SAFE_RELEASE(Modem); // Get Next ModemToSerialPort-Object hr = enumerator->Next(WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &ModemToSerial ), &retcnt ); } } }