See the question and my original answer on StackOverflow

You can read Internet Explorer COM Object's server from the registry (ususally, it will be hosted by shdocvw.dll or ieframe.dll in more recent versions), and load it manually, something like this:

TCHAR key[MAX_PATH];
// read CLSID_InternetExplorer COM Server path
SHRegGetPath(HKEY_CLASSES_ROOT, _T("CLSID\\{8856F961-340A-11D0-A96B-00C04FD705A2}\\InProcServer32"), NULL, key, 0);
HINSTANCE hInstance = LoadLibrary(PathFindFileName(key));
if (hInstance)
{
    DLLGETVERSIONPROC fn = (DLLGETVERSIONPROC)GetProcAddress(hInstance, "DllGetVersion");
    if (fn)
    {
        DLLVERSIONINFO2 version;
        ZeroMemory(&version, sizeof(DLLVERSIONINFO2));
        version.info1.cbSize = sizeof(DLLVERSIONINFO2);
        (*fn)((DLLVERSIONINFO*)&version);

        printf("Major:%u\n", version.ullVersion >> 48);
        printf("Minor:%u\n", (version.ullVersion >> 32) & 0xFFFF);
        printf("Build:%u\n", (version.ullVersion >> 16) & 0xFFFF);
        printf("QFE:%u\n", version.ullVersion & 0xFFFF);
    }
    FreeLibrary(hInstance);
}