-
February 19th, 2013, 12:35 PM
#1
WMI in C# .NET Giving Different Results to WMI in Native C DLL
Hey,
I'm using WMI in C# .NET to retrieve some hardware information, including the current Win32_VideoController "Name". In C# on Windows 8 for a lot (or possibly all) people it seems to obtain information about a completely different video controller to that of when my native C DLL requests the same information.
For example, in Windows 8 the name seems to say "Microsoft Basic Render Driver" with C# and "NVIDIA GeForce 550 TI" via my native DLL. Why would this happen?
Here's my C# code:
PHP Code:
ManagementObject managementObject1;
object object1;
string string1 = "";
foreach (QueryPair queryPair1 in new QueryPair[] { new QueryPair("Win32_Processor", "Name"), new QueryPair("Win32_VideoController", "Name") })
{
try
{
using (ManagementObjectSearcher managementObjectSearcher1 = new ManagementObjectSearcher (("SELECT * FROM " + queryPair1.Query)))
{
using (ManagementObjectCollection managementObjectCollection1 = managementObjectSearcher1.Get ())
{
using (ManagementObjectCollection.ManagementObjectEnumerator managementObjectEnumerator1 = managementObjectCollection1.GetEnumerator ())
{
if (managementObjectEnumerator1.MoveNext ())
{
managementObject1 = ((ManagementObject) managementObjectEnumerator1.Current);
object1 = managementObject1[queryPair1.Member];
string1 = (string1 + "|" + ((object1 != null) ? object1.ToString ().Replace("|", "-") : "?"));
}
}
}
}
}
catch
{
}
}
And here's my native C code:
PHP Code:
// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
//CoUninitialize();
return 1; // Program has failed.
}
// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
wbemConnectFlagUseMaxWait, // Security flags.
0, // Authority (for example, Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
pLoc->Release();
//CoUninitialize();
return 1; // Program has failed.
}
// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
pSvc->Release();
pLoc->Release();
//CoUninitialize();
return 1; // Program has failed.
}
GetWMIRequest(pSvc, L"Win32_VideoController", L"Name");
PHP Code:
BSTR GetWMIRequest(IWbemServices *pSvc, BSTR service, BSTR prop)
{
HRESULT hres;
// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM ") + service,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
VARIANT vtProp;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
// Get the value of the Name property
hr = pclsObj->Get(prop, 0, &vtProp, 0, 0);
VariantClear(&vtProp);
}
pEnumerator->Release();
pclsObj->Release();
return vtProp.bstrVal;
}
I know in the native code I'm explicitly connecting to the "ROOT\CIMV2" scope, but I did try doing that in C# and it made no difference.
Why would these 2 bits of code get information about 2 completely different video controllers on the same computer? And they even run in the same process. The C# code runs inside a C# .NET exe, and the native DLL is loaded by the C# .NET exe and called via an export in the DLL.
Help appreciated!
-
February 19th, 2013, 01:44 PM
#2
Re: WMI in C# .NET Giving Different Results to WMI in Native C DLL
Your code doesn't handle the case where more than one controller is returned.
-
February 19th, 2013, 04:47 PM
#3
Re: WMI in C# .NET Giving Different Results to WMI in Native C DLL
Originally Posted by Arjay
Your code doesn't handle the case where more than one controller is returned.
Yeah I did realise that, but:
1) Why would the native DLL get a different first returned controller to the C#? Are the lists reversed or something?
2) How could I make sure the same controller is returned in both sets of code? I don't want to do something unstable like comparing the "Name" string to "Microsoft Basic Render Driver", not to mention that it wouldn't necessarily come up with that if it grabs an alternate video controller on a non-Windows 8 machine.
Is there an entry in the Win32_VideoController that specifies if it's the primary device? I had a look through the entries but I can't see what I might be able to check.
Thanks.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|