01 uuid获取途径
js中有个组件 systeminformation
可以查到系统的UUID。
在windows中代码的大约如下。
exec(util.getWmic() + ' csproduct get /value', opts, function (error, stdout) {
if (!error) {
// let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0)[0].trim().split(/\s\s+/);
let lines = stdout.split('\r\n');
result.manufacturer = util.getValue(lines, 'vendor', '=');
result.model = util.getValue(lines, 'name', '=');
result.version = util.getValue(lines, 'version', '=');
result.serial = util.getValue(lines, 'identifyingnumber', '=');
result.uuid = util.getValue(lines, 'uuid', '=');
exec(util.getWmic() + ' /namespace:\\\\root\\wmi path MS_SystemInformation get /value', opts, function (error, stdout) {
if (!error) {
let lines = stdout.split('\r\n');
result.sku = util.getValue(lines, 'systemsku', '=');
}
if (callback) { callback(result); }
resolve(result);
});
}
if (callback) { callback(result); }
resolve(result);
});
原理可以cmd命令行运行windows命令行
WMIC csproduct list /format
结果如下:
Description=计算机系统产品
IdentifyingNumber=Default string
Name=Z370 HD3
SKUNumber=
UUID=03D502E0-045E-05A0-6B06-B40700080009
Vendor=Gigabyte Technology Co., Ltd.
Version=Default string
UUID=03D502E0-045E-05A0-6B06-B40700080009
02 c++ 实现
#include <Shlobj.h>
#include <Wbemidl.h>
#include <comdef.h>
#include <codecvt>
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "wbemuuid.lib")
bool get_system_uuid(std::string& uuid, std::string& device_name) {
bool bRet = false;
HRESULT hres;
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
if (FAILED(hres)) {
std::cout << "Failed to initialize COM library. Error code = 0x" << std::hex
<< hres << std::endl;
return bRet;
}
// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------
// hres = CoInitializeSecurity(
// NULL,
// -1, // COM authentication
// NULL, // Authentication services
// NULL, // Reserved
// RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
// RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
// NULL, // Authentication info
// EOAC_NONE, // Additional capabilities
// NULL // Reserved
//);
// if (FAILED(hres)) {
// std::cout << "Failed to initialize security. Error code = 0x" << std::hex
// << hres << std::endl;
// CoUninitialize();
// return bRet;
//}
// 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)) {
std::cout << "Failed to create IWbemLocator object."
<< " Err code = 0x" << std::hex << hres << std::endl;
CoUninitialize();
return bRet;
}
// 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
NULL, // Security flags.
0, // Authority (for example, Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres)) {
std::cout << "Could not connect. Error code = 0x" << std::hex << hres
<< std::endl;
pLoc->Release();
CoUninitialize();
return bRet;
}
std::cout << "Connected to ROOT\\CIMV2 WMI namespace" << std::endl;
// 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)) {
std::cout << "Could not set proxy blanket. Error code = 0x" << std::hex
<< hres << std::endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return bRet;
}
03 注意事项
比较重要的是:单独进程获取,没问题,如果进程中有其他com类应用,就需要注意。
比如:在chromium主进程中使用时,需要单独起一个线程来运行这个函数。才能正常运行。
1 不能调用 CoInitializeSecurity 函数
2 CoInitializeEx(0, COINIT_APARTMENTTHREADED);中的参数使用COINIT_APARTMENTTHREADED,而不是COINIT_MULTITHREADED。