WMI using native code

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
prem_kumar79Asked:
Who is Participating?
 
ZoppoConnect With a Mentor Commented:
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
 
ZoppoCommented:
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
 
prem_kumar79Author Commented:
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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
prem_kumar79Author Commented:
Thanks a lot for your help... :)
0
 
prem_kumar79Author Commented:
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
 
ZoppoCommented:
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
All Courses

From novice to tech pro — start learning today.