|
Hi
I have been having problems for ages in this area; my solution, based on this samples from MSDN, involves calling the following functions in this order:
CoInitializeSecurity
CoCreateInstance; I use CLSID_WbemLocator
ConnectServer; using the pIWbemLocator
CoSetProxyBlanket; passing pWbemServices as the parameter
Using this approach I have been able to perform remote queries. I will post an article on this if required. Hope it helps.
Happy programming
|
|
|
|
|
Hi Owen
In fact I did it myself but never had time to update it here. Too much busy nowadays. I hope to get it done in near future.
Regards
Imagine that you are creating a fabric of human destiny with the object of making men happy in the end, giving them peace and rest at last, but that it was essential and inevitable to torture to death only one tiny creature..and to found that edifice on its unavenged tears, would you consent to be the architect on those conditions? Tell me, and tell me the truth!
-Fyodor Dostoevsky, The Brothers Karamazov
|
|
|
|
|
hi
I hope i can come up with a new update if u wish to do it ..i too am able to connect to remote systems ( save different subnet and some issues involving NT machines ) and query values ...
regds
dharani babu s
|
|
|
|
|
Hi All,
I have written a VC++ code to query using COM API for WMI. The program returns zero records. The same query if I run using wbemtest.exe it returns me 16 records.
Could anybody help me why this happens ?
Thanks in advance
|
|
|
|
|
Hello...
I m trying to create the instance of Win32_Processor class in Windows98 OS through Visual Basic Programming. But Windows98 OS is not give error "Invalid Class Name". Is Windows98 does not support Win32_Processor ? Please tell me alternative way to access every information of CPU in Windows98 OS Platform through VB 6.0.
Im a Application Developer. Actually i want to put lock on my client's PC through the CPU's ProcessorId.If u have any other alternative way then tell me. I already used Serial No of HDD but it is not too much PowerFul Lock.
So try to give me Apropriate Approach ...
- Thank you ...
My E-Id is : alfa_soni@yahoo.com
|
|
|
|
|
Hello,
I am using WMI calls to get the currently logged in user name. This works in Win2k but does not in XP. Could anybody help me with this. Here is the code (ofcourse a simple modification done on Aamir Butt's code). Thanks to Aamir for the useful code.
This exactly fails on pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned) . The returned HRes value is -2147217405.
int main()
{
CoInitialize(NULL);
AfxMessageBox(_T("Getting the user name...."));
CComPtr pIWbemLocator = NULL;
CComPtr pWbemServices = NULL;
CComPtr pEnumObject = NULL;
CComBSTR bstrNamespace(_T("root\\cimv2"));
HRESULT hRes = pIWbemLocator.CoCreateInstance(CLSID_WbemAdministrativeLocator);
if (FAILED(hRes))
{
cout << _T("CoCreateInstance of IWbemLocator Failed") << endl;
AfxMessageBox(_T("CoCreateInstance of IWbemLocator Failed"));
return 0;
}
AfxMessageBox(_T("CoCreate successful"));
hRes = pIWbemLocator->ConnectServer(
bstrNamespace, // Namespace
NULL, // Userid
NULL, // PW
NULL, // Locale
0, // flags
NULL, // Authority
NULL, // Context
&pWbemServices
);
if (FAILED(hRes))
{
cout << _T("Failed to Connect Server") <<endl;
return 0;
}
ccombstr="" strquery(_t("select="" *="" from="" win32_computersystem"));=""
ccombstr="" strql(_t("wql"));
="" hres="pWbemServices-">ExecQuery(strQL, strQuery,WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject);
hRes = pWbemServices->ExecQuery(strQL, strQuery,WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject);
if (FAILED(hRes))
{
cout << _T("Failed to execute Query") << endl;
return 0;
}
ULONG uCount = 1, uReturned = 0;
CComPtr pClassObject;
hRes = pEnumObject->Reset();
if (FAILED(hRes))
cout << _T("Reset Failed") << endl;
CString strOb;
hRes = pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
if(FAILED(hRes))
{
cout << _T("Get Next Failed: %ld") << endl;
return 0;
}
_variant_t vProp;
CComBSTR strClassProp(_T("UserName"));
hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0);
if (FAILED(hRes))
{
cout << _T("Failed to get Class Object") << endl;
return 0;
}
_bstr_t bstrPath = &vProp;
CString strUserName((LPCTSTR)bstrPath);
CString strMessage;
int nIndex = strUserName.Find('\\');
if(nIndex != -1)
{
strMessage.Format(_T("The user name is : %s"), strUserName.Mid(nIndex+1));
AfxMessageBox(strMessage);
}
else
{
strMessage.Format(_T("The user name is : %s"), strUserName);
AfxMessageBox(strMessage);
}
AfxMessageBox(strMessage);
CoUninitialize();
return 1;
}
|
|
|
|
|
Anand you are doing everything fine except one. I have just updated my Article but it hasnt been done here on the Server. Hope it will be done in a few days. Well, you need to add this to your code.
CoInitializeSecurity( NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
0
);
This is because Windows XP needs security to be initialized. igoychev has already explained this in an answer earlier.
Think Negatively, It makes you creative
|
|
|
|
|
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
|
|
|
|
|