VS 2010 C++ MFC Problem z WMI Win32_TemperatureProbe

0

Witam,
W sieci znalazłem kod programu, który za pomocą WMI wyświetla nazwę procesora.
Wszystko jest OK gdy przy tworzeniu zapytania do WMI używam Win32_Processor.

        HRESULT hRes;
	BSTR strQuery = (L"Select * from Win32_Processor"); 
	BSTR strQL = (L"WQL"); 
	hRes = pWbemServices->ExecQuery(strQL, strQuery,WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject); 
 

Problem pojawia się gdy chcę przerobić ten kod programu, tak aby wyświetlał jakąś inną informację o komputerze, np. temperaturę procesora. Używam wtedy Win32_TemperatureProbe (zamiast Win32_Processor), a program się wysypuje podczas odczytu temperatury.

Kod programu poniżej:

void CCPU_TemperatureDlg::OnBnClickedButton1()
{
	// TODO: Add your control notification handler code here
	// TODO: Add your control notification handler code here
	CoInitialize(NULL);  //Inicjalizacja bibliotek COM


	//Security needs to be initialized in XP first and this was the major problem 
	//why it was not working in XP.

	if(CoInitializeSecurity( NULL,			
	-1,										
	NULL,
	NULL,
	RPC_C_AUTHN_LEVEL_PKT,
	RPC_C_IMP_LEVEL_IMPERSONATE,
	NULL,
	EOAC_NONE,
	0
	) != S_OK)
		//return;

	IWbemLocator * pIWbemLocator = NULL;   
	IWbemLocator * pIWbemLocator = NULL; 
	IWbemServices * pWbemServices = NULL;	
	IEnumWbemClassObject * pEnumObject  = NULL;

	BSTR bstrNamespace = (L"root\\cimv2");


	
	if(CoCreateInstance (									
            CLSID_WbemAdministrativeLocator,				
            NULL ,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , 
            IID_IUnknown ,
            ( void ** ) & pIWbemLocator	 		
            ) != S_OK)
				return;

	if(pIWbemLocator->ConnectServer(					
                bstrNamespace,  // Namespace			
                NULL,          // Userid
                NULL,           // PW
                NULL,           // Locale
                0,              // flags
                NULL,           // Authority
                NULL,           // Context
                &pWbemServices							
                ) != S_OK)
				return;
	


	HRESULT hRes;
	//BSTR strQuery = (L"Select * from MSAcpi_ThermalZoneTemperature");
	BSTR strQuery = (L"Select * from Win32_TemperatureProbe"); 
	BSTR strQL = (L"WQL");  
	hRes = pWbemServices->ExecQuery(strQL, strQuery,WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject);  
	
	if(hRes != S_OK)
	{
		MessageBox("Could not execute Query");
		return;
	}

	ULONG uCount = 1, uReturned;
	IWbemClassObject * pClassObject = NULL;


	hRes = pEnumObject->Reset(); 

	if(hRes != S_OK)
	{
		MessageBox("Could not Enumerate1");
		return;
	}

	hRes = pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
	if(hRes != S_OK)
	{
		MessageBox("Could not Enumerate2");
		return;
    }

	VARIANT v;
	//BSTR strClassProp = SysAllocString(L"LoadPercentage");
	BSTR strClassProp = SysAllocString(L"CurrentReading");               
	hRes = pClassObject->Get(strClassProp, 0, &v, 0, 0);
	if(hRes != S_OK)
	{
		MessageBox("Could not Get Value");
		return;
	}

	SysFreeString(strClassProp);
	
	_bstr_t bstrPath = &v;  //Just to convert BSTR to ANSI
	char* strPath=(char*)bstrPath;


	if (SUCCEEDED(hRes))
		MessageBox(strPath);
	else
		MessageBox("Error in getting object");

	VariantClear( &v );
	pIWbemLocator->Release();
	pWbemServices->Release();
	pEnumObject->Release();
	pClassObject->Release();
	CoUninitialize();

	 
}
 

Proszę o pomoc w rozwiązaniu problemu.

POZDRAWIAM

CurrentReading jest typu sint32, być może to jest problem?
Jeśli tak, to jak zmienić poniższy kod, aby wartość ta wyświetliła się w MessageBox?

 
VARIANT v;
        //BSTR strClassProp = SysAllocString(L"LoadPercentage");
        BSTR strClassProp = SysAllocString(L"CurrentReading");               
        hRes = pClassObject->Get(strClassProp, 0, &v, 0, 0);
        if(hRes != S_OK)
        {
                MessageBox("Could not Get Value");
                return;
        }
 
        SysFreeString(strClassProp);
 
        _bstr_t bstrPath = &v;  //Just to convert BSTR to ANSI
        char* strPath=(char*)bstrPath;
 
 
        if (SUCCEEDED(hRes))
                MessageBox(strPath);
        else
                MessageBox("Error in getting object");

0

Podsumowując:

  1. Znalazłeś kod, którego nie rozumiesz, na dodatek nie używasz odpowiedniego formatowania.
  2. Nie potrafisz korzystać z debugger'a, aby znaleźć informację kiedy program się wysypuje.
  3. Szukasz jelenia, który kod przeanalizuje kod i jak na oko będzie ok to wrzuci to do VS i zrobi robotę za Ciebie.
    Ehh..

Kiedy ten wyjątek leci dokładnie?

0

CurrentReading jest typu sint32. Po odczytaniu wartość ta przechowywana jest w zmiennej typu Variant, nazwa tej zmiennej w kodzie powyżej to v.
Jak prze-konwertować tą zmienną na np. CString, który będę mógł wyświetlić w MessageBox.
Rozwiązania szukałem w Googlach ale niestety nie znalazłem....

Proszę o pomoc

0

Zwykłe rzutowanie wystarczy. Oczywiście możesz rzutować tylko na taki typ, którego jest VARIANT. Nie możesz od razu na string, tylko do int. Potem chyba wiesz co dalej.

0

Witam,
Poniżej sposób w jaki zamieniam zmienną sint na cstring. Coś jest dalej nie tak, bo odczyty temperatury wyświetlane w MwssageBox wychodzą bardzo dziwne np. 5631968, 4648144, 6681000.....

 

VARIANT v;
	//BSTR strClassProp = SysAllocString(L"LoadPercentage");
	BSTR strClassProp = SysAllocString(L"CurrentReading");                 
	hRes = pClassObject->Get(strClassProp, 0, &v, 0, 0);
	if(hRes != S_OK)
	{
		MessageBox("Could not Get Value");
		return;
	}

	SysFreeString(strClassProp);

	int c = (int)&v;
	//_bstr_t bstrPath = &v;  //Just to convert BSTR to ANSI
	//char* strPath=(char*)bstrPath;
	char* strPath;
	CString a;
	a.Format("%d", c);



	

	if (SUCCEEDED(hRes))
		MessageBox(a);

1 użytkowników online, w tym zalogowanych: 0, gości: 1