Solved

WMI using native code

Posted on 2009-05-04
6
1,191 Views
Last Modified: 2012-05-06
I am trying to find the Reboot time (LastBootUpTime) of the machine, I was using a simple VB Script file to get it but I found one of the customers has disabled VB script

Using following method due to security restriction  
http://www.windowsecurity.com/whitepapers/Windows_Scripting_Host.html

following is the VB script I use cscript to get the reboot time.

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")
 
For Each objOS in colOperatingSystems
    dtmBootup = objOS.LastBootUpTime
    dtmLastBootupTime = WMIDateStringToDate(dtmBootup)
      Wscript.Echo "System Booted at : " & dtmLastBootupTime
Next
 
Function WMIDateStringToDate(dtmBootup)
    WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & "/" & _
        Mid(dtmBootup, 7, 2) & "/" & Left(dtmBootup, 4) _
            & " " & Mid (dtmBootup, 9, 2) & ":" & _
                Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup,13, 2))
End Function

I read there is way to make a WMI call using C++ but I am not that good in native code

Can someone point me to the native code in which I can get the reboot time using a WMI call.

Thanks in advance
0
Comment
Question by:prem_kumar79
  • 3
  • 3
6 Comments
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Hi prem_kumar79,

here's a code which does this in a Win32 C++ console application - don't wonder that it's much longer than the VB-code you posted; in VB it is much easier to access WMI object than in C++. Further it has complete error checking ...

Hope that helps,

ZOPPO


#include <string>

#include <sstream>

#include <iostream>

#include <Wbemidl.h>

#include <atlconv.h>

#pragma comment (lib, "wbemuuid.lib")
 

bool

GetLastBootUpTime( std::string& strValue )

{

	USES_CONVERSION;
 

	CoInitialize(NULL);
 

	bool bRet = false;
 

	if( S_OK == CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0 ) )

	{

		IWbemLocator * pIWbemLocator = NULL;

		IWbemServices * pWbemServices = NULL;

		IEnumWbemClassObject * pEnumObject  = NULL;
 

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

		if( S_OK != CoCreateInstance(

				CLSID_WbemAdministrativeLocator,

				NULL,

				CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,

				IID_IUnknown,

				( void ** )&pIWbemLocator

				)

			)

		{

			return false;

		}
 

		if( S_OK != pIWbemLocator->ConnectServer(

				bstrNamespace,  // Namespace

				NULL,          // Userid

				NULL,           // PW

				NULL,           // Locale

				0,              // flags

				NULL,           // Authority

				NULL,           // Context

				&pWbemServices

				)

			)

		{

			pIWbemLocator->Release();
 

			return false;

		}
 

		if ( S_OK != pWbemServices->ExecQuery(

				L"WQL",

				L"Select * from Win32_OperatingSystem",

				WBEM_FLAG_RETURN_IMMEDIATELY,

				NULL,

				&pEnumObject

				)

			)

		{

			pIWbemLocator->Release();

			pWbemServices->Release();
 

			return false;

		}

		

		ULONG uCount = 1, uReturned;

		IWbemClassObject * pClassObject = NULL;
 

		if ( S_OK != pEnumObject->Reset() )

		{

			pIWbemLocator->Release();

			pWbemServices->Release();

			pEnumObject->Release();
 

			return false;

		}
 

		VARIANT vData;
 

		while( S_OK == pEnumObject->Next( WBEM_INFINITE, uCount, &pClassObject, &uReturned ) )

		{

			if ( S_OK == pClassObject->Get( L"LastBootUpTime", 0, &vData, 0, 0 ) )

			{

				bRet = true;
 

				strValue = OLE2A( vData.bstrVal );
 

				std::stringstream ss;
 

				ss << strValue.substr( 4, 2 ) << _T( "\\" )

					<< strValue.substr( 6, 2 ) << _T( "\\" )

					<< strValue.substr( 0, 4 ) << _T( " " )

					<< strValue.substr( 8, 2 ) << _T( ":" )

					<< strValue.substr( 10, 2 ) << _T( ":" )

					<< strValue.substr( 12, 2 );
 

				strValue = ss.str();
 

				VariantClear( &vData );
 

				break;

			}

		}
 

		pIWbemLocator->Release();

		pWbemServices->Release();

		pEnumObject->Release();

		pClassObject->Release();

	}
 

	CoUninitialize();
 

	return bRet;

}
 

int _tmain( int argc, char* argv[] )

{

	std::string strTmp;
 

	if ( false != GetLastBootUpTime( strTmp ) )

	{

		std::cout << "Last boot up time: " << strTmp << std::endl;

	}

	else

	{

		std::cout << "Error: Can't retrieve last boot up time!" << std::endl;

	}
 

	return 0;

}

Open in new window

0
 

Author Comment

by:prem_kumar79
Comment Utility
Thanks for the code it works fine.
I just require one more change, the current VB script gives the output like

System Booted at : 5/4/2009 9:43:43 AM

This native code gives the output like
Last boot up time: 05\04\2009 09:43:43

That is in 24 hrs format I would like to have the output in 12 hr format with AM and PM.
It will be great if you can provide me with the changes.
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 50 total points
Comment Utility
Hi again,

ok, to do so you'll have to replace the lines 91-100 (inclusive) with the attached code.

I hope that helps,

ZOPPO
				struct tm tm = { 0 };
 

				tm.tm_mday = atoi( strValue.substr( 6, 2 ).c_str() );

				tm.tm_mon = atoi( strValue.substr( 4, 2 ).c_str() ) - 1;

				tm.tm_year = atoi( strValue.substr( 0, 4 ).c_str() ) - 1900;

				tm.tm_hour = atoi( strValue.substr( 8, 2 ).c_str() );

				tm.tm_min = atoi( strValue.substr( 10, 2 ).c_str() );

				tm.tm_sec = atoi( strValue.substr( 12, 2 ).c_str() );
 

				const int nLen = 128;

				TCHAR pszTime[ nLen ] = "";
 

				strftime( pszTime, nLen, "%#m/%#d/%Y %#I:%#M:%#S %p", &tm );
 

				strValue = pszTime;

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Closing Comment

by:prem_kumar79
Comment Utility
Thanks a lot for your help... :)
0
 

Author Comment

by:prem_kumar79
Comment Utility
I found when that when I try in the exe windows 2003 box the exe is not returning the time it shows
Error: Can't retrieve last boot up time!
#ifndef _WIN32_DCOM

#define _WIN32_DCOM

#endif
 

#include <string>

#include <sstream>

#include <iostream>

#include <Wbemidl.h>

#include <atlbase.h>

#pragma comment (lib, "wbemuuid.lib")

 

bool

GetLastBootUpTime( std::string& strValue )

{

	USES_CONVERSION;

 

	CoInitialize(NULL);

 

	bool bRet = false;

 

	if( S_OK == CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0 ) )

	{

		IWbemLocator * pIWbemLocator = NULL;

		IWbemServices * pWbemServices = NULL;

		IEnumWbemClassObject * pEnumObject  = NULL;

 

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

 

		if( S_OK != CoCreateInstance(

				CLSID_WbemAdministrativeLocator,

				NULL,

				CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,

				IID_IUnknown,

				( void ** )&pIWbemLocator

				)

			)

		{

			return false;

		}

 

		if( S_OK != pIWbemLocator->ConnectServer(

				bstrNamespace,  // Namespace

				NULL,          // Userid

				NULL,           // PW

				NULL,           // Locale

				0,              // flags

				NULL,           // Authority

				NULL,           // Context

				&pWbemServices

				)

			)

		{

			pIWbemLocator->Release();

 

			return false;

		}

 

		if ( S_OK != pWbemServices->ExecQuery(

				L"WQL",

				L"Select * from Win32_OperatingSystem",

				WBEM_FLAG_RETURN_IMMEDIATELY,

				NULL,

				&pEnumObject

				)

			)

		{

			pIWbemLocator->Release();

			pWbemServices->Release();

 

			return false;

		}

		

		ULONG uCount = 1, uReturned;

		IWbemClassObject * pClassObject = NULL;

 

		if ( S_OK != pEnumObject->Reset() )

		{

			pIWbemLocator->Release();

			pWbemServices->Release();

			pEnumObject->Release();

 

			return false;

		}

 

		VARIANT vData;

 

		while( S_OK == pEnumObject->Next( WBEM_INFINITE, uCount, &pClassObject, &uReturned ) )

		{

			if ( S_OK == pClassObject->Get( L"LastBootUpTime", 0, &vData, 0, 0 ) )

			{

				bRet = true;

 

				strValue = OLE2A( vData.bstrVal );

 

				std::stringstream ss;

 

				ss << strValue.substr( 4, 2 ) << ( "/" )

					<< strValue.substr( 6, 2 ) << ( "/" )

					<< strValue.substr( 0, 4 ) << ( " " )

					<< strValue.substr( 8, 2 ) << ( ":" )

					<< strValue.substr( 10, 2 ) << ( ":" )

					<< strValue.substr( 12, 2 );

 

				strValue = ss.str();

 

				VariantClear( &vData );

 

				break;

			}

		}

 

		pIWbemLocator->Release();

		pWbemServices->Release();

		pEnumObject->Release();

		pClassObject->Release();

	}

 

	CoUninitialize();

 

	return bRet;

}

 

int _tmain( int argc, char* argv[] )

{

	std::string strTmp;

 

	if ( false != GetLastBootUpTime( strTmp ) )

	{

		std::cout << "Last boot up time: " << strTmp << std::endl;

	}

	else

	{

		std::cout << "Error: Can't retrieve last boot up time!" << std::endl;

	}

 

	return 0;

}

Open in new window

0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Well, I don't know why this code cannot retrieve that data in Win2003, but you can simply remove that message by deleting these lines (131-134):

> else
> {
>  std::cout << "Error: Can't retrieve last boot up time!" << std::endl;
> }
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now