Solved

WMI using native code

Posted on 2009-05-04
6
1,201 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 31

Expert Comment

by:Zoppo
ID: 24296384
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
ID: 24304312
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 31

Accepted Solution

by:
Zoppo earned 50 total points
ID: 24305295
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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 

Author Closing Comment

by:prem_kumar79
ID: 31577494
Thanks a lot for your help... :)
0
 

Author Comment

by:prem_kumar79
ID: 24314449
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 31

Expert Comment

by:Zoppo
ID: 24314501
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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

776 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