如何获取Windows系统所在磁盘的型号与序列号及解决C++调用命令报错问题
如何获取Windows系统所在磁盘的型号与序列号及解决C++调用命令报错问题
我来分享一下如何精准获取Windows系统盘的物理磁盘型号和序列号,以及解决C++调用命令时踩过的那些坑。
首先得明确:我们要的是物理磁盘本身的型号和序列号,而不是vol C:返回的Windows给逻辑分区分配的序列号——这俩完全不是一回事。
命令行下的实现步骤
- 第一步,先定位系统所在的物理磁盘编号
执行命令:wmic bootconfig get description
返回结果类似Description\Device\Harddisk3\Partition1,这里的数字3就是对应物理磁盘的编号(对应PHYSICALDRIVE3)。 - 第二步,通过编号查询磁盘信息
把第一步得到的数字替换到下面的命令里:
注意这里的反斜杠转义:在CMD里直接用wmic diskdrive where DeviceID='\\\\.\\PHYSICALDRIVE3' get model,serialnumber\\\\.\\PHYSICALDRIVE3就能正常执行,但如果是在PowerShell或者C++代码里,需要更多的转义处理。
解决C++调用时的报错问题
之前尝试用PowerShell命令Get-Disk (Get-Partition -DriveLetter 'C').DiskNumber在C++里通过system()调用会报错,原因是system()默认调用的是CMD,而Get-Disk是PowerShell专属命令,CMD根本识别不了。
另外直接在C里调用wmic命令时,遇到了ERROR: Invalid query的问题,这是因为C字符串里的反斜杠需要双重转义:原本的\\.\PHYSICALDRIVE要写成\\\\\\\\.\\\\PHYSICALDRIVE——相当于把每个反斜杠都转义两次。
最终可用的C++代码实现
以下是经过调试后的完整代码,能直接获取并输出合并后的系统盘型号和序列号:
#include <iostream> #include <string> #include <array> #include <memory> #include <stdexcept> 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(); } } int main() { try { // 获取系统所在物理磁盘的编号 std::string indexStr = exec("wmic bootconfig get description"); // 从返回结果中提取磁盘编号(比如从\Harddisk3\中拿到3) size_t lastBackslash = indexStr.find_last_of("\\"); char indexChar = indexStr.at(lastBackslash - 1); std::string index(1, indexChar); // 拼接正确的wmic查询命令,注意反斜杠的双重转义 std::string queryCmd = "wmic diskdrive where DeviceID='\\\\\\\\.\\\\PHYSICALDRIVE" + index + "' get model,serialnumber"; std::string diskInfo = exec(queryCmd.c_str()); // 清理输出内容,去掉表头和多余空格 replaceString(diskInfo, "Model", ""); replaceString(diskInfo, "SerialNumber", ""); replaceString(diskInfo, " ", ""); // 输出合并后的型号和序列号 std::cout << diskInfo << std::endl; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } return 0; }
代码说明:
exec函数:通过_popen执行命令并捕获输出结果,比system()更适合获取返回内容。replaceString函数:用来清理输出里的多余表头(Model、SerialNumber)和空格,得到简洁的合并结果。- 主函数:先获取磁盘编号,再拼接正确的查询命令,最后处理输出得到我们需要的内容。
备注:内容来源于stack exchange,提问作者Devorious
相关产品推荐
相关产品推荐

