I am writing my own C++ code to read the computer model and manufacturer on a Windows computer by reading and parsing the registry key
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/mssmbios/Data/SMBiosData
Is there any library function in Windows / C++ / Visual Studio that allows me to get this information directly?
asked Sep 6, 2012 at 12:45
Giorgio
5,2036 gold badges46 silver badges71 bronze badges
-
4That information is available through the WMI (Windows Machine Instrumentation), but that is far form a simple library function.rodrigo– rodrigo2012年09月06日 12:47:55 +00:00Commented Sep 6, 2012 at 12:47
-
So I had rather parse the registry entry and look for the relevant entries myself (?).Giorgio– Giorgio2012年09月06日 12:52:17 +00:00Commented Sep 6, 2012 at 12:52
-
Probably, yes, but I know little about the WMI API. Maybe it will surprise me and be too easy...rodrigo– rodrigo2012年09月06日 15:02:00 +00:00Commented Sep 6, 2012 at 15:02
-
I have managed to read the content of the registry entry. I am trying to parse it using the information I have found at codeproject.com/Articles/24730/SMBIOS-Peek. It does not seem too difficult. bvi is also my friend at the moment.Giorgio– Giorgio2012年09月06日 15:23:50 +00:00Commented Sep 6, 2012 at 15:23
-
I wrote a small program according to the format indicated in the article I have cited. I have assumed that the SMBiosData contains a sequence of entries, each with that table format. Unfortunately, this does not seem to be that case: at the beginning of the data there are bytes 0x00, 0x02, and this must be wrong since I would expect the second byte to be at least 0x04 because it should indicate the size of the formatted section of the first entry (see the format description to understand what this means).Giorgio– Giorgio2012年09月07日 09:21:49 +00:00Commented Sep 7, 2012 at 9:21
2 Answers 2
The steps you need are explained on Creating a WMI Application Using C++. MSDN even includes a sample program. You just need to change two strings.
- Change
SELECT * FROM Win32_ProcesstoSELECT * FROM Win32_ComputerSystem - Change
NametoManufacturerand then again forModel.
answered Sep 7, 2012 at 18:39
Raymond Chen
45.4k12 gold badges100 silver badges145 bronze badges
Sign up to request clarification or add additional context in comments.
1 Comment
Stu
I had no idea you were even on this site, Raymond. Allow me to grovel for a minute -- and done. Much better now.
With the help of the Microsoft example code, I was able to create this method.
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
std::pair<CString,CString> getComputerManufacturerAndModel() {
// Obtain the initial locator to Windows Management on a particular host computer.
IWbemLocator *locator = nullptr;
IWbemServices *services = nullptr;
auto hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator);
auto hasFailed = [&hResult]() {
if (FAILED(hResult)) {
auto error = _com_error(hResult);
TRACE(error.ErrorMessage());
TRACE(error.Description().Detach());
return true;
}
return false;
};
auto getValue = [&hResult, &hasFailed](IWbemClassObject *classObject, LPCWSTR property) {
CString propertyValueText = "Not set";
VARIANT propertyValue;
hResult = classObject->Get(property, 0, &propertyValue, 0, 0);
if (!hasFailed()) {
if ((propertyValue.vt == VT_NULL) || (propertyValue.vt == VT_EMPTY)) {
} else if (propertyValue.vt & VT_ARRAY) {
propertyValueText = "Unknown"; //Array types not supported
} else {
propertyValueText = propertyValue.bstrVal;
}
}
VariantClear(&propertyValue);
return propertyValueText;
};
CString manufacturer = "Not set";
CString model = "Not set";
if (!hasFailed()) {
// Connect to the root\cimv2 namespace with the current user and obtain pointer pSvc to make IWbemServices calls.
hResult = locator->ConnectServer(L"ROOT\\CIMV2", nullptr, nullptr, 0, NULL, 0, 0, &services);
if (!hasFailed()) {
// Set the IWbemServices proxy so that impersonation of the user (client) occurs.
hResult = CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
if (!hasFailed()) {
IEnumWbemClassObject* classObjectEnumerator = nullptr;
hResult = services->ExecQuery(L"WQL", L"SELECT * FROM Win32_ComputerSystem", WBEM_FLAG_FORWARD_ONLY |
WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &classObjectEnumerator);
if (!hasFailed()) {
IWbemClassObject *classObject;
ULONG uReturn = 0;
hResult = classObjectEnumerator->Next(WBEM_INFINITE, 1, &classObject, &uReturn);
if (uReturn != 0) {
manufacturer = getValue(classObject, (LPCWSTR)L"Manufacturer");
model = getValue(classObject, (LPCWSTR)L"Model");
}
classObject->Release();
}
classObjectEnumerator->Release();
}
}
}
if (locator) {
locator->Release();
}
if (services) {
services->Release();
}
CoUninitialize();
return { manufacturer, model };
}
answered Jan 31, 2017 at 1:35
Daniel Ryan
7,1205 gold badges51 silver badges66 bronze badges
Comments
lang-cpp