哪位高手知道不通过读取注册表,如何获得WINDOWS的产品ID

ahejn 2004-08-10 04:12:22
如题,不是通过读取注册表方式获得.所谓ID,就是从我的电脑 右键 属性里看到的那一串类似 55661-011- ............. 的数字
...全文
911 点赞 收藏 16
写回复
16 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
geland 2004-08-21
调用WMI必须做这些事情,初始化COM,连接到名字空间,再得到某个提供类的实例,MSDN 上有例子。
回复
ahejn 2004-08-21
楼上,这是托管代码吧,我VC不太熟悉。这段代码我看到过,发现很复杂。
能否给一个相对简单的例子,就比如读取PRODUCT ID。
麻烦您了。
回复
oyljerry 2004-08-21
嗯,2000下可以直接修改注册表得到
回复
geland 2004-08-19

HRESULT ConnectServerWMI ( OUT IWbemLocator** ppiWmiLoc ,
OUT IWbemServices** ppiWmiServ ,
const char* csNamespace ,
const char* csUsername ,
const char* csPassword )
{
if (NULL == ppiWmiServ || NULL == ppiWmiLoc) {
printf("Invalid argument\n");
return E_INVALIDARG;
}

HRESULT hres;
hres = CoCreateInstance ( CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator ,
(LPVOID *) ppiWmiLoc );

if (FAILED(hres)) {
DisplayError(TEXT("CoCreateInstance"),GetLastError());
return hres;
}

CComBSTR bstrNamespace(csNamespace);

if (!csPassword || !csUsername)
{
hres = (*ppiWmiLoc)->ConnectServer(bstrNamespace, NULL, NULL ,
0, NULL, 0, 0, ppiWmiServ );
}
else
{
// connect server using password and username
CComBSTR bstrUsername(csUsername), bstrPassword(csPassword);

hres = (*ppiWmiLoc)->ConnectServer(bstrNamespace, bstrUsername,
bstrPassword, 0, NULL, 0, 0,
ppiWmiServ );
}

if (FAILED(hres))
{
(*ppiWmiLoc)->Release();
DisplayError(TEXT("ConnectServer"),GetLastError());
return hres;
}


hres = CoSetProxyBlanket( *ppiWmiServ ,
RPC_C_AUTHN_WINNT ,
RPC_C_AUTHZ_NONE ,
NULL,
RPC_C_AUTHN_LEVEL_CALL ,
RPC_C_IMP_LEVEL_IMPERSONATE ,
NULL,
EOAC_NONE);

if(FAILED(hres))
{
(*ppiWmiLoc)->Release();
(*ppiWmiServ)->Release();
DisplayError(TEXT("CoSetProxyBlanket"),GetLastError());
return hres;
}

return hres;
}

HRESULT GetLastErrorWMI (string& csErrRef, HRESULT hresErr)
{
IWbemStatusCodeText * pStatus = NULL;

HRESULT hres = CoCreateInstance(CLSID_WbemStatusCodeText, 0, CLSCTX_INPROC_SERVER,
IID_IWbemStatusCodeText, (LPVOID *) &pStatus);

if(S_OK == hres)
{
CComBSTR bstrError;
hres = pStatus->GetErrorCodeText(hresErr, 0, 0, &bstrError);

if(S_OK != hres)
bstrError = SysAllocString(L"Get last error failed");

USES_CONVERSION;
csErrRef = OLE2T(bstrError);

pStatus->Release();
}

return hres;
}

HRESULT EnumInstancesWMI ( IN IWbemServices* piWmiServ ,
OUT IEnumWbemClassObject** ppiWmiEnum ,
const char* csInstName )
{
if (NULL == piWmiServ || NULL == ppiWmiEnum)
{
printf("Invalid argument\n");
return E_INVALIDARG;
}

HRESULT hres;
CComBSTR bstrObjectName(csInstName);

hres = piWmiServ->CreateInstanceEnum( bstrObjectName ,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY ,
NULL ,
ppiWmiEnum);
if (FAILED(hres))
{
DisplayError(TEXT("CreateInstanceEnum"),GetLastError());
return hres;
}
return hres;
}

static
HRESULT EnumInstPropNameWMI ( IN IWbemClassObject* piappObj,
OUT LPSAFEARRAY* ppsarProp )
{
if (NULL == ppsarProp || NULL == piappObj)
{
printf("Invalid argument\n");
return E_INVALIDARG;
}
// GetNames methods will create SAFEARRAY,
// but on entry this parameter must point to NULL
if (NULL != *ppsarProp)
{
SafeArrayDestroy(*ppsarProp);
delete *ppsarProp;
*ppsarProp = NULL;

if (NULL == ppsarProp)
return E_INVALIDARG;
}

HRESULT hres;
hres = piappObj->GetNames( NULL,
WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,
NULL,
ppsarProp);
return hres;
}

HRESULT EnumInstPropNameWMI ( IN IWbemClassObject* piappObj,
OUT ArgVector& psarPropRef )
{
HRESULT hres;
SAFEARRAY* pSafeArrProp = NULL;

psarPropRef.clear();

hres = EnumInstPropNameWMI(piappObj, &pSafeArrProp );

if (WBEM_S_NO_ERROR != hres)
return hres;

long lLower, lUpper;
SafeArrayGetLBound(pSafeArrProp , 1, &lLower);
SafeArrayGetUBound(pSafeArrProp , 1, &lUpper);

for (long i = lLower; i <= lUpper; ++i)
{
CComBSTR bstrPropName;

if (S_OK != (hres = SafeArrayGetElement(pSafeArrProp, &i, &bstrPropName)) )
{
if (NULL != pSafeArrProp)
SafeArrayDestroy(pSafeArrProp);
return hres;
}

USES_CONVERSION;
psarPropRef.push_back( OLE2T(bstrPropName) );

}

if (NULL != pSafeArrProp)
SafeArrayDestroy(pSafeArrProp);

return hres;
}

HRESULT ExecMethodWMI ( IN IWbemServices* piWmiServ ,
const char* csMethodName,
const char* csClassName ,
const char* csClassPath ,
const char* csObjectPath,
const ArgVector* csarrPropNames /*=NULL*/,
VARIANT* arrVarInArg/*=NULL*/,
const int size_t/*=0*/)
{
// sanity checks
if (NULL == piWmiServ)
{
printf("Invalid argument\n");
return E_INVALIDARG;
}

if (( NULL != csarrPropNames && NULL == arrVarInArg) ||
( NULL == csarrPropNames && NULL != arrVarInArg) )
{
printf("Invalid argument\n");
return E_INVALIDARG;
}

if (NULL != csarrPropNames)
{
if(size_t != (*csarrPropNames).size())
return E_INVALIDARG;
}

IWbemClassObject* pClassObj = NULL;
IWbemClassObject* pOutParam = NULL;
IWbemClassObject* pInParam = NULL;

IWbemClassObject* pInClass = NULL;
IWbemClassObject* pOutClass = NULL;
IWbemCallResult* pCallRrs = NULL;

CComBSTR bstrMethodName ( csMethodName);
CComBSTR bstrClassName ( csClassName );
CComBSTR bstrClassPath ( csClassPath );
CComBSTR bstrObjectPath ( csObjectPath);

HRESULT hres;
hres = piWmiServ->GetObject(bstrClassName, 0, NULL, &pClassObj, NULL);

if (WBEM_S_NO_ERROR == hres)
{
// get the input-argument class object and create an instance.
// pInClass == NULL indicates that no input parameters needed.
hres = pClassObj->GetMethod(bstrMethodName, 0, &pInClass, NULL);

if (WBEM_S_NO_ERROR == hres)
{
if( NULL != pInClass)
{
// create instance copy
if(WBEM_S_NO_ERROR == (hres=pInClass->SpawnInstance(0, &pInParam)) )
{
// set each property
for (long i = 0; i < size_t; ++i)
{
CComBSTR bstrPropName( (*csarrPropNames)[i].c_str() );
hres = pInParam->Put(bstrPropName, 0, &arrVarInArg[i], 0);

// DUF!!! Put failed, check the properties and their types
if (WBEM_S_NO_ERROR != hres)
break;
}
}
}
// finally call the method
if (WBEM_S_NO_ERROR == hres)
{
hres = piWmiServ->ExecMethod(bstrObjectPath,
bstrMethodName,
0,
NULL,
pInParam,
&pOutParam,
&pCallRrs);
}
}
}

// free all resources
if (NULL != pOutParam)
{
// but first we get the output parameters here
CComBSTR bstrClassObj;
hres = pOutParam->GetObjectText(0, &(bstrClassObj.m_str));

USES_CONVERSION;

printf("\n\nThe object text of the output object is:\n%s", OLE2T(bstrClassObj));

pOutParam->Release();
}

if (NULL != pClassObj) pClassObj->Release();

if (NULL != pInParam) pInParam->Release();

if (NULL != pInClass) pInClass->Release();

if (NULL != pOutClass) pOutClass->Release();

return hres;
}

HRESULT GetClassMethodsWMI ( IN IWbemClassObject* piappObj,
OUT ArgVector& csarrMethods)
{

if (NULL == piappObj)
return E_INVALIDARG;

csarrMethods.clear();

USES_CONVERSION;

HRESULT hres;
hres = piappObj->BeginMethodEnumeration(0);

while(WBEM_S_NO_ERROR == hres)
{
CComBSTR bstrMethodName;
hres = piappObj->NextMethod(0, &bstrMethodName, NULL, NULL);

if (WBEM_S_NO_ERROR == hres)
csarrMethods.push_back(OLE2T(bstrMethodName));

}

return piappObj->EndMethodEnumeration();
}

回复
geland 2004-08-19

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

#include <windows.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <atlbase.h>
#include <tchar.h>
#include <vector>
#include <string>

using std::string;

typedef std::vector<std::string> ArgVector;

#ifndef OUT
#define OUT
#endif

#ifndef IN
#define IN
#endif

//
//错误信息显示函数
//
void DisplayError( LPTSTR szAPI, DWORD dwError );

//
//连接到指定的名字空间
//
HRESULT ConnectServerWMI (OUT IWbemLocator** ppiWmiLoc ,//接收初始化后的IWbemLocator指针
OUT IWbemServices** ppiWmiServ ,//接收初始化后的IWbemServices指针
const char* csNamespace ,//名字空间
const char* csUsername ,//用户名
const char* csPassword //用户口令
);

//
//得到一个类的枚举实例
//
HRESULT EnumInstancesWMI (IN IWbemServices* piWmiServ ,//已经初始化的IWbemServices指针
OUT IEnumWbemClassObject** ppiWmiEnum ,//接收初始化后的IEnumWbemClassObject指针
const char* csInstName //提供类实例的名称
);

//
//取得最后的错误信息
//
HRESULT GetLastErrorWMI (OUT string& csErrRef, //接收初始化后的错误信息
IN HRESULT hresErr //错误码
);

//
//枚举类的属性名列表
//
HRESULT EnumInstPropNameWMI ( IN IWbemClassObject* piappObj, //初始化后的IWbemClassObject指针
OUT ArgVector& psarPropRef//接收属性列表的变量
);


//HRESULT EnumInstPropNameWMI ( IN IWbemClassObject* piappObj,
// OUT LPSAFEARRAY* psarProp );

//
//在一个类上执行方法
//
HRESULT ExecMethodWMI (IN IWbemServices* piWmiServ ,//初始化后的IWbemServices指针
const char* csMethodName,//方法名
const char* csClassName ,//类名
const char* csClassPath ,//类的路径,
const char* csObjectPath,//对象的路径(ie:\\namespace\root\CIMV2:Win32_Process.Handle="1556")
const ArgVector* csarrPropNames = NULL,//属性名列表
VARIANT* arrVarInArg = NULL,//参数列表
const int size_t = 0//参数个数
);

//
//取得一个提供类的方法名列表
//
HRESULT GetClassMethodsWMI (IN IWbemClassObject* piappObj, //初始化后的IWbemClassObject指针
OUT ArgVector& csarrMethods //接收方法列表的变量
);


//
//Win32_Process:Create() pass
//Win32_Process:Terminate() pass
//
int main(int argc, char* argv[])
{
HRESULT hr;
IWbemLocator* piWmiLoc=NULL;
IWbemServices* piWmiServ=NULL;
IEnumWbemClassObject* piWmiEnum=NULL;
IWbemClassObject* pClass = NULL;

// Initialize COM and connect up to CIMOM

hr = CoInitialize(0);
if (FAILED(hr))
{
printf("CoInitialize returned 0x%x:", hr);
return 1;
}
hr=ConnectServerWMI(&piWmiLoc,&piWmiServ,"root\\CIMV2",0,0);
if(FAILED(hr))
{
printf("ConnectServerWMI fail!\n");
CoUninitialize();
return 1;
}

// hr=EnumInstancesWMI(piWmiServ,&piWmiEnum,"Win32_SystemDriver");
hr=EnumInstancesWMI(piWmiServ,&piWmiEnum,argv[1]);
if(FAILED(hr))
{
printf("EnumInstancesWMI fail!\n");
CoUninitialize();
return 1;
}

//show all instance
while(WBEM_S_NO_ERROR==hr)
{
ULONG uReturned;
IWbemClassObject* apObj;

hr = piWmiEnum->Next( WBEM_INFINITE, 1, &apObj, &uReturned );

if ( SUCCEEDED( hr ) && 1 == uReturned)
{
BSTR bstrObj;
HRESULT hres;
hres = apObj->GetObjectText(0, &bstrObj);
if (SUCCEEDED( hres ))
{
wprintf(L"%s\n",bstrObj);
}
SysFreeString(bstrObj);
}

}
CoUninitialize();
return 0;
}

void DisplayError( LPTSTR szAPI, DWORD dwError )
{
LPTSTR lpBuffer = NULL;

FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpBuffer, 0, NULL );

_tprintf( TEXT("%s failed:\n"), szAPI );
_tprintf( TEXT(" error code = %d\n"), dwError );
_tprintf( TEXT(" message = %s\n"), lpBuffer );

LocalFree( lpBuffer );
}
回复
ahejn 2004-08-18
geland老兄能否给出一段vc下面使用WMI的示例代码,我只找到了一段.NET下面的托管代码示例,万分感谢。
回复
geland 2004-08-16
具体WMI读出来的是不是注册表值我也不清楚,WMI应该有自己的数据库,但是不是和注册表有什么联系,不知道!
回复
ahejn 2004-08-16
再顶,没有高手帮忙就结贴啦。
回复
ahejn 2004-08-14
楼上那位仁兄,不知道WMI读出来的是不是注册表值,我的是XP,修改了注册表键发现系统属性里ID没有改变,我怀疑是不是有什么隐藏的API?
回复
taianmonkey 2004-08-13
HKEY hKey = NULL;
TCHAR tcProductType[MAX_PATH];
DWORD dwBufLen;

RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
0, KEY_QUERY_VALUE, &hKey );

RegQueryValueEx( hKey, "ProductID", NULL, NULL,
(LPBYTE)tcProductType, &dwBufLen);

RegCloseKey( hKey );

AfxMessageBox(tcProductType);
回复
tabris17 2004-08-13
2000也是放在注册表中的

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductId


我改了这个值,系统属性中的值也相应变了
回复
geland 2004-08-13
可以用WMI ,读取Win32_OperatingSystem类的SerialNumber字段值就是你要的东东!
回复
蒋晟 2004-08-13
98是存在注册表里面的,2000是存在INI里面的,XP不知道
回复
ahejn 2004-08-11
顶一下先,因为修改注册表中的PRODUCT ID后,发现在系统属性里的产品ID并没有相应改变,说明有办法不访问注册表直接读出这个ID,哪位老大知道.请教啦
回复
Pipi0714 2004-08-10
他是干什么的。
回复
aspnetwuxueyou 2004-08-10
不知道,只知道通过注册表可以读出来
回复
相关推荐
发帖
硬件/系统
创建于2007-09-28

2597

社区成员

VC/MFC 硬件/系统
申请成为版主
帖子事件
创建了帖子
2004-08-10 04:12
社区公告
暂无公告