如何获得嵌入式IE ActiveX控件的版本?

时间:2014-05-03 19:40:10

标签: c++ internet-explorer mfc activex activexobject

我刚刚在我的C ++(MFC)应用程序中嵌入了IE / Web浏览器ActiveX控件。我很好奇如何获得用于它的IE版本?

1 个答案:

答案 0 :(得分:0)

这有点像黑客攻击,但您可以使用mshtml.dll作为任何IE控件的integral part,并检索其版本。接下来是我的一个项目的代码片段:

#define SIZEOF(f) (sizeof(f) / sizeof(f[0]))

HMODULE hModMshtl = ::GetModuleHandle(L"mshtml.dll");
if(hModMshtl)
{
    TCHAR buffMshtl[MAX_PATH];
    buffMshtl[0] = 0;
    ::GetModuleFileName(hModMshtl, buffMshtl, SIZEOF(buffMshtl));
    buffMshtl[SIZEOF(buffMshtl) - 1] = 0;

    CString strProdName;
    VS_FIXEDFILEINFO vi;
    if(GetFileVersionAndProductName(buffMshtl, &vi, &strProdName))
    {
        //Got it
        _tprintf(L"%s v.%d.%d.%d.%d",
            strProdName.GetString(),
            (DWORD)((vi.dwProductVersionLS & 0xFFFF0000) >> 16),
            (DWORD)(vi.dwProductVersionLS & 0xFFFF),
            (DWORD)((vi.dwProductVersionMS & 0xFFFF0000) >> 16),
            (DWORD)(vi.dwProductVersionMS & 0xFFFF)
            );
    }
}

以及如何获得其版本:

BOOL GetFileVersionAndProductName(LPCTSTR pFilePath, VS_FIXEDFILEINFO* pOutVersionInfo, CString* pOutProductName)
{
    BOOL bRes = FALSE;
    CString strFilePath = pFilePath;
    LPCTSTR pDescBuf = NULL;

    struct LANGANDCODEPAGE {
      WORD wLanguage;
      WORD wCodePage;
    };

    CString strProdName;

    BYTE* pData = NULL;
    if(!strFilePath.IsEmpty())
    {
        //Get size needed
        DWORD dwDummy;
        DWORD dwSz = ::GetFileVersionInfoSize((LPTSTR)strFilePath.GetString(), &dwDummy);
        if(dwSz > 0)
        {
            //Reserve mem
            pData = new (std::nothrow)BYTE[dwSz];
            if(pData)
            {
                //Retrieve version info
                if(::GetFileVersionInfo((LPTSTR)strFilePath.GetString(), NULL, dwSz, pData))
                {
                    UINT nczBufLn;
                    VS_FIXEDFILEINFO* pVi = NULL;
                    if(VerQueryValue(pData, _T("\\"), (VOID**)&pVi, &nczBufLn))
                    {
                        if(pVi &&
                            nczBufLn >= sizeof(*pVi) &&
                            pVi->dwSignature == 0xFEEF04BD)
                        {
                            //Got it
                            bRes = TRUE;

                            if(pOutVersionInfo)
                                *pOutVersionInfo = *pVi;
                        }
                    }


                    struct LANGANDCODEPAGE
                    {
                        WORD wLanguage;
                        WORD wCodePage;
                    } *lpTranslate = NULL;

                    // Read the list of languages and code pages.
                    UINT cbTranslate;
                    if(VerQueryValue(pData,  L"\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &cbTranslate))
                    {
                        //Get first language
                        if(lpTranslate &&
                            cbTranslate >= sizeof(*lpTranslate))
                        {
                            //Retrieve product name
                            CString strBlock;
                            strBlock.Format(L"\\StringFileInfo\\%04x%04x\\ProductName", 
                                lpTranslate[0].wLanguage,
                                lpTranslate[0].wCodePage);

                            UINT dwProdLn = 0;
                            VOID* lpBufferName = NULL;
                            if(VerQueryValue(pData, strBlock, &lpBufferName, &dwProdLn))
                            {
                                //Get name
                                memcpy(strProdName.GetBufferSetLength(dwProdLn), lpBufferName, dwProdLn * sizeof(TCHAR));
                                strProdName.ReleaseBuffer();
                            }
                        }
                    }
                }
            }
        }
    }


    if(pOutProductName)
        *pOutProductName = strProdName;

    //Free mem
    if(pData)
        delete[] pData;

    return bRes;
}