|
But the above does not work for windows 7. can anyone help with this. UserName returned is empty when query "Select * win32ComputerSystem" is run.
|
|
|
|
|
Thanks Aamir for the nice sample. Unfortunately I wasn't able to make it work (see thread "another trap"). So I rewrote the code myselve from scratch. This was possible because you showed me in your sample what I have to call. Thank you Aamir.
Make a console application and paste the following code, that's all. Remember to disable "precompiled headers" (or place the #includes into the file "stdafx.h".) If you don't want to install the WMI-SDK you can copy the file "WbemCli.h" to your project and take care that the file "wbemdisp.tlb" can be found.(Beginners: Look microsoft platform sdk on the ms website, install it (and the WMI SDK along with it) and be sure the paths to "microsoft sdk\include" and "microsoft sdk\lib" are pointed in [vc++ menu]:extras\options)
#include <comdef.h>
#include <windows.h>
#import "wbemdisp.tlb" no_namespace
#include <wbemcli.h>
#include <crtdbg.h> //for _ASSERT
void SetDNS();
int main(int argc, char* argv[])
{
CoInitialize(NULL);
SetDNS();
CoUninitialize();
return 0;
}
void SetDNS()
{
ISWbemServicesPtr serv;
ISWbemLocatorPtr loc;
HRESULT hr=loc.CreateInstance(__uuidof(SWbemLocator));
_ASSERT(!FAILED(hr));
bstr_t sNull;
serv=loc->ConnectServer("", "root\\cimv2", sNull, sNull, sNull, sNull, 0L, NULL);
ISWbemObjectSetPtr objSet=serv->ExecQuery("Select * from win32_Processor", "WQL", 0, NULL);
IEnumVARIANTPtr en=objSet->_NewEnum;
variant_t d;
ULONG cnt;
while(en->Next(1,&d,&cnt) == S_OK){
ISWbemObjectPtr obj(d);
ISWbemPropertySetPtr ps(obj->Properties_);
ISWbemPropertyPtr prop(ps->Item("LoadPercentage",0));
variant_t v(prop->GetValue());
bstr_t bsLoad(v.vt==VT_NULL ? "" : v);
MessageBox(NULL,bsLoad,"WMISample",0);
}
}
Have fun
|
|
|
|
|
The maillist DB ate my brackets. Here's the corrected code.
#include <comdef.h>
#include <windows.h>
#import "wbemdisp.tlb" no_namespace
#include <Wbemcli.h>
#include <crtdbg.h> //for _ASSERT
void SetDNS();
int main(int argc, char* argv[])
{
CoInitialize(NULL);
SetDNS();
CoUninitialize();
return 0;
}
void SetDNS()
{
ISWbemServicesPtr serv;
ISWbemLocatorPtr loc;
HRESULT hr=loc.CreateInstance(__uuidof(SWbemLocator));
_ASSERT(!FAILED(hr));
bstr_t sNull;
serv=loc->ConnectServer("", "root\\cimv2", sNull, sNull, sNull, sNull, 0L, NULL);
ISWbemObjectSetPtr objSet=serv->ExecQuery("Select * from win32_Processor", "WQL", 0, NULL);
IEnumVARIANTPtr en=objSet->_NewEnum;
variant_t d;
ULONG cnt;
while(en->Next(1,&d,&cnt) == S_OK){
ISWbemObjectPtr obj(d);
ISWbemPropertySetPtr ps(obj->Properties_);
ISWbemPropertyPtr prop(ps->Item("LoadPercentage",0));
variant_t v(prop->GetValue());
bstr_t bsLoad(v.vt==VT_NULL ? "" : v);
MessageBox(NULL,bsLoad,"WMISample",0);
}
}
|
|
|
|
|
You want to set a value ?
#include <windows.h>
#import "wbemdisp.tlb" no_namespace
#include <Wbemcli.h>
#include <crtdbg.h> //for _ASSERT
##include <string>
using namespace std;
void SetDNS();
int main(int argc, char* argv[])
{
CoInitialize(NULL);
SetDNS();
CoUninitialize();
return 0;
}
void SetDNS()
{
ISWbemServicesPtr serv;
ISWbemLocatorPtr loc;
HRESULT hr=loc.CreateInstance(__uuidof(SWbemLocator));
_ASSERT(!FAILED(hr));
bstr_t sNull;
serv=loc->ConnectServer("", "root\\cimv2", sNull, sNull, sNull, sNull, 0L, NULL);
ISWbemObjectSetPtr objSet=serv->ExecQuery("Select * from Win32_NetworkAdapterConfiguration", "WQL", 0, NULL);
IEnumVARIANTPtr en=objSet->_NewEnum;
variant_t d;
ULONG cnt;
while(en->Next(1,&d,&cnt) == S_OK)
{
ISWbemObjectPtr obj(d);
ISWbemPropertySetPtr ps(obj->Properties_);
variant_t v(ps->Item("Caption",0)->GetValue());
string bsName(bstr_t(v.vt==VT_NULL ? "" : v));
if(bsName.find("... Network Interface Name ...") != string::npos)
{
// Set DNSDomain
string sDNSDomain("domain.org");
ISWbemMethodPtr m=obj->Methods_->Item("SetDNSDomain",0);
ISWbemObjectPtr inp=m->InParameters->SpawnInstance_(0);
inp->Properties_->Item("DNSDomain",0)->PutValue(&variant_t(sDNSDomain));
obj->ExecMethod_(L"SetDNSDomain",inp,0,NULL);
}
}
}
This sets the DNS of a network interface card. Replace "... Network Interface Name ..." by the name of the card (right-click, choose properties of your network connection and on WinXP you will see the name above the bindings-checkbox-list.) (Or yust trace to see the possible values ...)
Have Fun
Roelof
|
|
|
|
|
Hi Roelof
Thanx for a nice addition to the Article. I havent tested it yet but I am sure this must be working as you must have worked it out quite a lot.
Well, when I wrote this Article, Frankly speaking, I didnt know that there is anything called WMI SDK. I only had platform SDK which didnt include it coz probably it was a previous version. Anyway, I did it with a little bit of help from MSDN and some help from .. umm nothing
A few weeks later I came to know that there is something like WMI SDK so I had thought to do it with its help but couldn't due to lack of time. Anyways, u did that great job. Congrats for that and Thanx as well
Regards
I feel like I am diagonally parked in a parallel universe
|
|
|
|
|
PutValue(&variant_t(sDNSDomain));
must be
PutValue(&variant_t(sDNSDomain.c_str()));
...
(I do not use <string> and forgot that before posting the sample ...)
|
|
|
|
|
I can't thank you guys enough for the examples! Us beginning MFC coders need all the help we can get
I'm trying to update an entry in WMI.
Here is the info:
root\\CCM\\Policy\\Machine\\ActualConfig
PermissionRequired
I want to set its value to 0. An example on how to do this would be fantastic, I cant seem to get it working
Any help is greatly appreciated!
|
|
|
|
|
I can't thank you guys enough for the examples! Us beginning MFC coders need all the help we can get
I'm trying to update an entry in WMI.
Here is the info:
root\\CCM\\Policy\\Machine\\ActualConfig
PermissionRequired
I don't see any methods avail like SetPermissionRequired" when i click on the methods tab in wmi object explorer
I want to set its value to 0. An example on how to do this would be fantastic, I cant seem to get it working
Any help is greatly appreciated!
|
|
|
|
|
Hello,
At first, thanks for your code : it works very well! (Thanks for Aamir too...).
Until now it was very easy for me to do that with vb but not with c++...
I try it with Win32_Process class and Name property. It's OK.
Can you please tell me how can i add a condition on the ProcessId value in the while loop?
while(en->Next(1,&d,&cnt) == S_OK)
{
ISWbemObjectPtr obj(d);
ISWbemPropertySetPtr ps(obj->Properties_);
ISWbemPropertyPtr prop(ps->Item("Name",0));
variant_t v(prop->GetValue());
bstr_t bsLoad(v.vt==VT_NULL ? "" : v);
If ProcessId is equal to myValue then
MessageBox(NULL,bsLoad ,"WMISamples",0);
}
I tried something with adding : "ISWbemPropertyPtr procId(ps->Item("ProcessId",0));" but it doesn't work.
Thanks in advance.
JoDeb
|
|
|
|
|
Hello,
at first thanks for the code sniplet. It shows quickly what do do and what to call when you have heard the term MSI yust 2 hours ago and want to play a bit ... Thanks a lot.
Ok, after I added "Wbemuuid.lib" to the linker settings and removed the troublesome slashes ("root\\cimv2") the execution reaches the "enumerator.next" line. The error WBEM_E_ACCESS_DENIED (0x80041003) is thrown. If I set the ExecQuery method to synchronous execution (by removing the WBEM_FLAG_RETURN_IMMEDIATELY flag) I get this error message allready in the ExecQuery-Call. So "ExecQuery" fails stating I have no rights. This is strange because a VB test app works with this query and because I am logged on as Admin. Any ideas ?
(latest Win XP, VSS V6 SP5, latest SDK)
Thanks,
Roelof
|
|
|
|
|
Hi,
You receive WBEM_E_ACCESS_DENIED
on
pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
because you don't have permisions to get the class object.
You must set the security of your process with:
hr = CoInitializeSecurity( NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
0
);
and all will be fine - at least it works for me on WinXP.
Aaamir, it will be good if you add this code in the example.
|
|
|
|
|
The project finally build after inserting the #pragma comment(lib,"Wbemuuid.lib")Application gets the pIWbemLocator interface pointer but when u invoke ConnectServer
..there is crash!!
Any views ??
Deepu Abraham K
|
|
|
|
|
You need to check whether pIWbemLocator is getting the valid pointer or not. If its not getting, there may be a problem in WMI Service running on your pc. Check it in SCM if its running or not. Further u didnt need to add that pragma in it. The code was written with the understanding that Platform SDK is installed. On Installing, Platform SDK automatically sets the directories and if it doesnt do so, u can do it manually from VC's directory settings.
I was born Intelligent, but education ruined me.....
|
|
|
|
|
Aamir,
In SCM I hve checked.The WMI service is running but "Windows Management Instrumentation Driver Extensions" is not running !.
Any ways the crash has gone !! I have replaced the namespace as "BSTR bstrNamespace = (L"\\root\\cimv2");".
Now the crash is now in
hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
cause hr = pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
is failing and it says WBEM_E_ACCESS_DENIED.The pClassObject and uReturned is showing NULL !!
Its strange yesterday when I have checked I got WBEM_E_INVALID_CLASS error !!
Any comment on this Aamir?
DAK
|
|
|
|
|
Hi Fundoo7,
You receive WBEM_E_ACCESS_DENIED
on
pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
because you don't have permisions to get the class object.
You must set the security of your process with:
hr = CoInitializeSecurity( NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
0
);
and all will be fine - at least it works for me on WinXP.
Aaamir, it will be good if you add this code in the example.
|
|
|
|
|
Hi Amir,
Tried your code, compiled fine, while executing ExecQuery method is consistently failing with Error code 0x80041008 indicating "One of the parameters to the call is not correct". Don't know what went wrong. Thanks in advance.
-regards
Anand
|
|
|
|
|
Hi,
One intresting point is its working fine in WinXP and the problem is consistent in Win 2K professional. Any possible causes Aamir!.
-regards
Anand
|
|
|
|
|
Hi,
I too got the same error. So, I tried this.
Instead of ExecQuery(), use GetObject() API to get a pointer to IWbemClassObject. This interface will expose methods like
BeginEnumeration(), Get(), Put().
-Carolene
Carolene S
|
|
|
|
|
Hi,
I think the problem will be in BSTR allocation, All those BSTR args to ExecQuery needs to be allocated using SysAllocString call and it will happen by default in WinXP.
--rgds
--
"Man thrives, oddly enough, only in the presence of a challenging environment."- L. Ron Hubbard
|
|
|
|
|
Hi
Please tell me where can i get the file "wbemidl.h"
shailesh
|
|
|
|
|
It comes with the SDK. This can be downloaded from Microsoft's Web site.
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
System Management Server (SMS) 2.0 SP2 should be installed in ur machine to
get wbemidl.h
The url is
http://download.microsoft.com/download/C/4/F/C4F5FB61-F52B-436F-B436-81ADDC813DD5/sms20sdk.exe
Carolene S
|
|
|
|
|
Hi amir,
Your code was very helpfull. I was getting a runtime error that the "memory could not be read", when i debugged it i found that 'CoCreateInstance' does not instantiates the IWbemLocator, it returns a '-2147221164' which i am unable to understand. This error is not constant i.e. sometimes the function works also and returns normal. when i restart the PC it starts working. I am totally confused. Please Help me
|
|
|
|
|
I installed System Management Server(SMS) 2.0 SP2 which inturn installed wbemidl.h and other relevant lib files
Carolene S
|
|
|
|
|
HI
You can get all these things by installing Platform SDK. Simple Solution
Cheerz
Aamir
I was born Intelligent, but education ruined me.....
|
|
|
|
|