chromium 05 在chromium中获取系统的UUID

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。

猜你喜欢

转载自blog.csdn.net/longji/article/details/81878344