ocx一般会在注册表中注册一个CLSID,一般在HKEY_LOCAL_MACHINE/SOFTWARE/CLASSES/CLSID
下。
读取ocx的版本号主要分为以下几个步骤:
1.获得ocx的CLSID
有些ocx提供GetClsid函数,该函数的功能是返回其CLSID结构,然后下面的程序将该CLSID结构进行解析:
GetCLSID()
{
CLSID clsid;
memset(&clsid,0,sizeof(CLSID));
clsid = m_pXCDFRDCtrl->GetClsid();//m_pXCDFRDCtrl为ocx控件的指针
CString sid = "";
CString lastid = "";
lastid.Format("%X%X-%X%X%X%X%X%X}",clsid.Data4[0],clsid.Data4[1],
clsid.Data4[2],clsid.Data4[3],clsid.Data4[4],clsid.Data4[5],
clsid.Data4[6],clsid.Data4[7]);
sid.Format("{%X-%X-%X-",clsid.Data1,clsid.Data2,clsid.Data3);
sid += lastid;
return sid;
}
这里解析出来的sid为{68A2CDE0-F378-46E2-9446-BC4179CCF339},一般CLSID在注册表的如下位置中:
HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/
2.获得ocx的注册路径
读注册表中的值
程序如下:
GetOcxPath(const CString clsid)
{
HKEY key;
DWORD dwType;
CString RegDir;
char szPath[MAX_PATH] = {0};
DWORD dwSize = MAX_PATH;
LONG lReturn = ERROR_SUCCESS;
RegDir.LoadString(IDS_OCX_PATH); //这里的IDS_OCX_PATH为
// HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/
// IDS_OCX_PATH在我的程序中不识别,我仍然不知道这个宏是在哪定义的
RegDir += clsid;
RegDir += "//InprocServer32";
lReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegDir, 0, KEY_QUERY_VALUE, &key);
lReturn = RegQueryValueEx(key, NULL, NULL, &dwType, (LPBYTE)szPath, &dwSize);
return szPath;
}
这里的注册表键InprocServer32存储了ocx的注册路径,读取到szPath中返回。
3.获得ocx的版本号
完成此功能的API函数为GetFileVersion(ocxPath),这里的ocxPath是指步骤2返回的注册路径
GetFileVersion(CString& strFileName)
{
CString strTempName = strFileName;
DWORD dwFileType = VFT_UNKNOWN;
DWORD dwVerInfoBytes;
DWORD dwHandle;
LPBYTE pVerInfo = NULL;
VS_FIXEDFILEINFO* pFixedFileInfo = NULL;
UINT uiLength;
HRESULT hResult = S_OK;
char* pBuffer = NULL;
CString strVersion = "";
//Call this API first to get the Version
dwVerInfoBytes = GetFileVersionInfoSize(strTempName.GetBuffer(0),&dwHandle);
if (dwVerInfoBytes == 0)
return HRESULT_FROM_WIN32(::GetLastError());
//Allocate memory to hold the version information for the specified file.
try
{
pVerInfo = new BYTE[dwVerInfoBytes];
}
catch(CMemoryException* e)
{
e->Delete();
}
if(::GetFileVersionInfo(strTempName.GetBuffer(0),0,dwVerInfoBytes,pVerInfo) && ::VerQueryValue(pVerInfo, _T("//"), (LPVOID*)&pFixedFileInfo, &uiLength))
{
//format the version number into the format such as 2.1.0.0
strVersion.Format("%d.%d.%d.%d",
HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
HIWORD(pFixedFileInfo->dwFileVersionLS),
LOWORD(pFixedFileInfo->dwFileVersionLS));
return strVersion;
}
这里返回的strVersion即是ocx的版本号!
获取ocx本身版本号
TCHAR szFullPath[MAX_PATH];
DWORD dwVerInfoSize = 0;
DWORD dwVerHnd;
VS_FIXEDFILEINFO * pFileInfo;
GetModuleFileName(theApp.m_hInstance, szFullPath, sizeof(szFullPath));
dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
if (dwVerInfoSize)
{
// If we were able to get the information, process it:
HANDLE hMem;
LPVOID lpvMem;
unsigned int uInfoSize = 0;
hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
lpvMem = GlobalLock(hMem);
GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpvMem);
::VerQueryValue(lpvMem,(LPTSTR)_T("\\"), (void**)&pFileInfo, &uInfoSize);
int ret = GetLastError();
WORD m_nProdVersion[4];
// Product version from the FILEVERSION of the version info resource
m_nProdVersion[0] = HIWORD(pFileInfo->dwProductVersionMS);
m_nProdVersion[1] = LOWORD(pFileInfo->dwProductVersionMS);
m_nProdVersion[2] = HIWORD(pFileInfo->dwProductVersionLS);
m_nProdVersion[3] = LOWORD(pFileInfo->dwProductVersionLS);
CString strVersion ;
strVersion.Format(_T("The file's version : %d.%d.%d.%d"),m_nProdVersion[0],
m_nProdVersion[1],m_nProdVersion[2],m_nProdVersion[3]);
// strVersion就是版本号;
GlobalUnlock(hMem);
GlobalFree(hMem);
}