Based on what I can find on the internet this doesn't seem to be something a lot of people do but I'm pretty stuck so I'm going to put it out here. I'm using WMI in C++ to try to manipulate SQL Server settings. I have the following code that doesn't return a result from my WMI query and I'm at a loss as to why:
hr = pLoc->ConnectServer(CComBSTR(L"root\\Microsoft\\SqlServer\\ComputerManagement10"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc);
// ----- Check for success and set proxy blanket here -----
IEnumWbemClassObject* pClassEnum = 0;
hr = pSvc->ExecQuery(_bstr_t("WQL"), _bstr_t("SELECT * FROM FilestreamSettings"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pClassEnum);
if (SUCCEEDED(hr) && pClassEnum)
{
ULONG uReturn = 0;
while (pClassEnum && !myInstanceFound)
{
hr = pClassEnum->Next(WBEM_INFINITE, 1, &pObjInstance, &uReturn);
if (0 == uReturn || !pObjInstance)
{
break;
}
// Get the value of the InstanceName property - the SQL Server instance name
CComVariant vtProp;
hr = pObjInstance->Get(L"InstanceName", 0, &vtProp, 0, 0);
if (SUCCEEDED(hr) && (VT_BSTR) == vtProp.vt)
{
if (vtProp.bstrVal == _bstr_t('MyInstance'))
{
myInstanceFound = true;
}
}
}
.
.
.
}
The ExecQuery command succeeds. The pClassEnum enumerator object is not null, so the while loop executes. The call to 'Next', however, does not return an object (pObjectInstance is null) and &uReturn is 0 (which, as I understand it means that the call to 'Next' returned 0 results). However, if I run the same query in the wbemtest tool, I get two results (which is correct, as I have 2 SQL Server instances on this machine). I have limited C++ skills and this is my first time with WMI. Not only do I not see what's wrong here, I'm not even sure what else to try. The few code samples I've seen suggest this code should be correct. Any help would be greatly appreciated!
Thanks, Dennis
Update: The call to Next() actually returns S_FALSE. Which, if I'm reading the docs correctly, mostly just confirms the issue of not getting a result. Next() returns S_FALSE if there are less than the number of requested results (in my case, less than 1 - or in other words, 0).
Update #2: This same code does work on my laptop (well, the Next() call does anyway). Differences are: Does work on my laptop - Win 10, Sql Server 2019 (have to change namespace to be ComputerManagement15 instead of 10), FileStream already enabled. Does not work - Win 7 VM, Sql Server 2008, FileStream not enabled. A query using Wbemtest tool gets the correct data in both cases. Just thought I'd post in case this helps.
FYI, in case anyone stumbles across this: I didn't technically solve this, in that I never got my C++ code to work. I wrote some C# code using SQL Server Management Objects (basically a wrapper over WMI) and made it into a COM server that I could call from C++. Even this didn't work directly because my C# COM server kept getting an "Access Denied" even if I ran the C++ COM client application as Administrator. What eventually worked was to extract the SSMO code out into its own C# console app which I then ran from my C# COM server as its own process using the "run as" verb so it would run as Administrator. This finally managed to enable Filestream on my SQL Server instance. It's possible there was a better/easier way to get this done but I found something that worked (although it was pretty kludgy). So if there's a chance this helps anyone else, I'm putting it out there.