Solved

WMI using native code

Posted on 2009-05-04
6
1,203 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

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

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Find Visual Studio Tools 2 113
object oriented programming on screen browser tutorial lesson 2 82
sorting efficency of sorting algorithm 30 122
Gaming Software 1 19
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…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

821 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