It works for me by doubling the "\" :
(I cannot paste : 4 \ and 2 \ after DeviceID=**)
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
I was trying to get the following to work (I only need it for Windows x64 10+):
#include <iostream>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd, "r"), _pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void main() {
std::cout << exec("wmic bootconfig get description");
std::cout << exec("wmic diskdrive where DeviceID='\\.\PHYSICALDRIVE3' get model,serialnumber");
}
The first exec is running fine and giving the right return, but I'm having problems with the second exec, where I'm getting: ERROR: Description = Invalid query. In my search for a fix for that error, I found that because I'm using C++ I should be using native wmi queries, but unfortunately each result with code examples that I found were "like 3 pages" of code. Does anyone know of some more simple examples for wmi queries?
As for the code, I'm trying to get the model and serial number of the disk that the OS is installed on for some unique identification of app install and some other minor checks. And for this, I found that using wmic bootconfig get description
, you can parse that result (Description\Device\Harddisk3\Partition1, 3 is the index) and get the index of the disk the OS is installed on, then using that index and wmic diskdrive where DeviceID='\\.\PHYSICALDRIVE3' get model,serialnumber
where you change the 3 from PHYSICALDRIVE3 with the index from last command, you get the model and serial number. The code above is just a test to see the commands working, later I was going to parse the result and update the second exec call, right now it's using the index for my PC that I know were the OS is installed.
And yes, I know that the user can simply install the OS on a different disk and so the model and/or serial number would be different, but having to go though all that is enough of a hindrance to actually affect my use case, as I only care when the app is launched, and not on how many machines is installed on, that is IF the user finds that I'm using this verification method in the first place.
Any help is appreciated!
//Edit based on the suggestion on accepted answer I tried with more \ and in the end I made it work. I gave up on trying to use native wmi, and I made it work with CMD call like this which also parses the returns and in the end you get straight model and serial number.
#include <iostream>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd, "r"), _pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void replaceString(std::string& subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
void main() {
std::string index = exec("wmic bootconfig get description");
index = index.at(index.find_last_of("\\") - 1);
std::string modelSerialNumber = "wmic diskdrive where DeviceID='\\\\\\\\.\\\\PHYSICALDRIVE" + index + "' get model,serialnumber";
modelSerialNumber = exec(modelSerialNumber.c_str());
replaceString(modelSerialNumber, "Model", "");
replaceString(modelSerialNumber, "SerialNumber", "");
replaceString(modelSerialNumber, " ", "");
std::cout << modelSerialNumber;
}
The output will be: KINGSTONSA2000M8250GXXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX.
. For my use case I needed the model and the serial number united like that.
It works for me by doubling the "\" :
(I cannot paste : 4 \ and 2 \ after DeviceID=**)