如何使用VC++代码获取系统唯一标识?

3

我是vc++语言的新手,想要使用vc++语言获取系统唯一标识。请问是否有人能够帮助我编写代码来获取系统唯一标识?


3
系统有唯一标识符的原因是什么? - anon
2
“系统唯一标识”是什么?它是在当前进程运行的系统范围内保证唯一的ID,还是唯一标识当前系统的ID? - jon hanson
我认为您需要提供更多的上下文信息。您能告诉我们这个唯一标识符在应用程序中将如何使用吗?这将使我们能够决定哪种解决方案可能或不可能是适当的。 - Rich
系统具有唯一的ID,可以在Windows中使用WMI查询。 - Code Name Jack
6个回答

2

1
那如何识别系统? - anon
2
没有任何函数可以生成相同的 ID,因此此函数不以任何方式标识系统。 - Kirill V. Lyadvinsky
回答上面的三条评论,您需要生成并存储GUID,然后使用它来识别您的计算机在更广泛的系统中,例如网络或任何其他上下文中。这与从网络卡获取MAC地址没有区别,只是这不需要您的系统具有网络卡。使用GUID比使用MAC地址更加自由。 - Rich
这并没有回答问题,不能保证唯一标识符会相同。 - Code Name Jack

2

至少有三个原因 - 可能没有网络卡,可能有多个网络卡,网络卡可能已更换。 - anon
如果有多个网络卡,请选择第一个。如果网络卡更改,则需要重新注册过程。如果没有网络卡,请将机器捐赠给博物馆并购买新的。;.)我同意MAC地址并不是100%的解决方案,但它应该适用于绝大多数情况。 - Rich
回想起来,生成GUID而不是使用MAC地址可能更好。然后就不需要安装网络卡了。话虽如此,除非首先连接到网络,否则什么系统需要唯一标识符呢?……嗯……我们确实需要从问题中获得更多上下文。 - Rich
不仅可以切换网络卡,还可以欺骗MAC地址,有很多简单的免费程序可以做到这一点。甚至Linksys路由器也有一个菜单选项来欺骗路由器的MAC地址。 - Kelly Elton
@kelton52,当然可以。我们不知道唯一标识符是否要在受信任的环境中使用。在不受信任的环境中,MAC地址是不合适的。 - Rich
唯一可信的环境是这个人,在他/她的电脑上使用这个程序。就是这样。只要你至少移除了这个人,它就不再是可信的。 - Kelly Elton

1

如果您想基于特定机器创建唯一ID,我能想到的其中一种方法是使用老牌的boost库。

例如,您可以查找名为UUID(GUID生成)的boost候选库之一,也可以查找boost::filesystem。使用文件系统,您可以获取某些系统文件的创建日期,并使用这些字符串生成GUID。

只是一个想法,希望能有所帮助。

  • 您可以在此处找到UUID库

    • 您可以在此处找到Filesystem库的文档

这个程序可以识别Windows安装的日期。如果我需要重新安装系统或者对文件进行修改,那么就会生成一个新的ID。 - anon

0

我见过使用的一个值是C驱动器的硬盘卷标ID。但是,当您更换驱动器时,它会发生变化。


0

我认为到目前为止的答案和对它们的回应表明,真正的答案不是编写需要唯一系统ID的代码。实际上,这很容易做到(因为没有这样的ID),这也是编写应用程序的唯一明智方式。任何依赖于驱动器序列号、MAC地址等的东西,在系统更改或升级时必然会出现问题。


0

您可以通过对“Win32_ComputerSystemProduct”类进行WMI查询来完成。

HRESULT hres;

// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------

hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) { return 1; }

// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------

hres = CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
    nullptr, EOAC_NONE, nullptr);
if (FAILED(hres)) { return 1; }

// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = nullptr;
hres = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<LPVOID *>(&pLoc));
if (FAILED(hres)) { return 1; }

// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method

IWbemServices *pSvc = nullptr;

// 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"), nullptr, nullptr, nullptr, NULL, nullptr, nullptr, &pSvc);

if (FAILED(hres)) { pLoc->Release();        CoUninitialize();        return 1; }


// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------

hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
    RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);

if (FAILED(hres)) { pSvc->Release();        pLoc->Release();        CoUninitialize();        return 1; }

// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----

// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = nullptr;
hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_ComputerSystemProduct"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    nullptr,
    &pEnumerator);

if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; }

// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------

IWbemClassObject *pclsObj = nullptr;
ULONG uReturn = 0;

HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
VARIANT vtProp;

// Get the value of the Name property
hr = pclsObj->Get(L"UUID", 0, &vtProp, 0, 0);
wcout << " OS Name : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);

pclsObj->Release();

// Cleanup
// ========

pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();

return 0;  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接