获取文件的详细信息中的文件说明信息

问题相关代码,请勿粘贴截图

GetFileDescription(const std::string& szModuleName, std::string& RetStr)
我的解答思路和尝试过的方法

查了一些东西,很多都是复制粘贴,很杂乱

我想要达到的结果

想要获取图中文件说明的信息

img

ModulVer.h:

////////////////////////////////////////////////////////////////
// 1998 Microsoft Systems Journal
//
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
#ifndef __MODULEVER_H
#define __MODULEVER_H

// tell linker to link with version.lib for VerQueryValue, etc.
#pragma comment(linker, "/defaultlib:version.lib")

//////////////////
// CModuleVersion version info about a module.
// To use:
//
// CModuleVersion ver
// if (ver.GetFileVersionInfo("_T("mymodule))) {
//        // info is in ver, you can call GetValue to get variable info like
//        CString s = ver.GetValue(_T("CompanyName"));
// }
//
// You can also call the static fn DllGetVersion to get DLLVERSIONINFO.
//
class CModuleVersion : public VS_FIXEDFILEINFO {
protected:
    BYTE* m_pVersionInfo;    // all version info

    struct TRANSLATION {
        WORD langID;            // language ID
        WORD charset;            // character set (code page)
    } m_translation;

public:
    CModuleVersion();
    virtual ~CModuleVersion();

    BOOL        GetFileVersionInfo(LPCTSTR modulename);
    CString GetValue(LPCTSTR lpKeyName);
    static BOOL DllGetVersion(LPCTSTR modulename, DLLVERSIONINFO& dvi);
};

#endif


ModulVer.cpp:

////////////////////////////////////////////////////////////////
// 1998 Microsoft Systems Journal
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
// CModuleVersion provides an easy way to get version info
// for a module.(DLL or EXE).
//
#include <afxwin.h>
#include <shlwapi.h>
#include "ModulVer.h"

CModuleVersion::CModuleVersion()
{
    m_pVersionInfo = NULL;                // raw version info data
}

//////////////////
// Destroy: delete version info
//
CModuleVersion::~CModuleVersion()
{
    delete [] m_pVersionInfo;
}

//////////////////
// Get file version info for a given module
// Allocates storage for all info, fills "this" with
// VS_FIXEDFILEINFO, and sets codepage.
//
BOOL CModuleVersion::GetFileVersionInfo(LPCTSTR modulename)
{
    m_translation.charset = 1252;        // default = ANSI code page
    memset((VS_FIXEDFILEINFO*)this, 0, sizeof(VS_FIXEDFILEINFO));

    // get module handle
    TCHAR filename[_MAX_PATH];
    HMODULE hModule = ::GetModuleHandle(modulename);
    if (hModule==NULL && modulename!=NULL)
        return FALSE;

    // get module file name
    DWORD len = GetModuleFileName(hModule, filename,
        sizeof(filename)/sizeof(filename[0]));
    if (len <= 0)
        return FALSE;

    // read file version info
    DWORD dwDummyHandle; // will always be set to zero
    len = GetFileVersionInfoSize(filename, &dwDummyHandle);
    if (len <= 0)
        return FALSE;

    m_pVersionInfo = new BYTE[len]; // allocate version info
    if (!::GetFileVersionInfo(filename, 0, len, m_pVersionInfo))
        return FALSE;

    LPVOID lpvi;
    UINT iLen;
    if (!VerQueryValue(m_pVersionInfo, _T("\\"), &lpvi, &iLen))
        return FALSE;

    // copy fixed info to myself, which am derived from VS_FIXEDFILEINFO
    *(VS_FIXEDFILEINFO*)this = *(VS_FIXEDFILEINFO*)lpvi;

    // Get translation info
    if (VerQueryValue(m_pVersionInfo,
        "\\VarFileInfo\\Translation", &lpvi, &iLen) && iLen >= 4) {
        m_translation = *(TRANSLATION*)lpvi;
        TRACE("code page = %d\n", m_translation.charset);
    }

    return dwSignature == VS_FFI_SIGNATURE;
}

//////////////////
// Get string file info.
// Key name is something like "CompanyName".
// returns the value as a CString.
//
CString CModuleVersion::GetValue(LPCTSTR lpKeyName)
{
    CString sVal;
    if (m_pVersionInfo) {

        // To get a string value must pass query in the form
        //
        //    "\StringFileInfo\<langID><codepage>\keyname"
        //
        // where <lang-codepage> is the languageID concatenated with the
        // code page, in hex. Wow.
        //
        CString query;
        query.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),
            m_translation.langID,
            m_translation.charset,
            lpKeyName);

        LPCTSTR pVal;
        UINT iLenVal;
        if (VerQueryValue(m_pVersionInfo, (LPTSTR)(LPCTSTR)query,
                (LPVOID*)&pVal, &iLenVal)) {

            sVal = pVal;
        }
    }
    return sVal;
}

// typedef for DllGetVersion proc
typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);

/////////////////
// Get DLL Version by calling DLL's DllGetVersion proc
//
BOOL CModuleVersion::DllGetVersion(LPCTSTR modulename, DLLVERSIONINFO& dvi)
{
    HINSTANCE hinst = LoadLibrary(modulename);
    if (!hinst)
        return FALSE;

    // Must use GetProcAddress because the DLL might not implement
    // DllGetVersion. Depending upon the DLL, the lack of implementation of the
    // function may be a version marker in itself.
    //
    DLLGETVERSIONPROC pDllGetVersion =
        (DLLGETVERSIONPROC)GetProcAddress(hinst, _T("DllGetVersion"));

    if (!pDllGetVersion)
        return FALSE;

    memset(&dvi, 0, sizeof(dvi));             // clear
    dvi.cbSize = sizeof(dvi);                 // set size for Windows

    return SUCCEEDED((*pDllGetVersion)(&dvi));
}


dllver.cpp

#pragma comment(lib,"user32")
#include <stdio.h>
#include <string.h>
#include <afxwin.h>
#include <windows.h>
#include <shlwapi.h>
#include "ModulVer.h"
TCHAR szText[MAX_PATH] = TEXT("Could not load DLL");
int v=0;
void GetDllVersion(LPCTSTR lpszDllName) {
    HINSTANCE hinstDll;

    hinstDll = LoadLibrary(lpszDllName);
    if (hinstDll) {
        DLLGETVERSIONPROC pDllGetVersion;

        /*
        You must get this function explicitly because the DLL might not implement
        the function. Depending upon the DLL, the lack of implementation of the
        function may be a version marker in itself.
        */
        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress( hinstDll,TEXT("DllGetVersion"));

        if (pDllGetVersion) {
            DLLVERSIONINFO dvi;
            HRESULT hr;

            ZeroMemory(&dvi, sizeof(dvi));
            dvi.cbSize = sizeof(dvi);

            hr = (*pDllGetVersion)(&dvi);

            if (SUCCEEDED(hr)) {
                wsprintf( szText,
                          TEXT("DLL Version = %d.%02d\nBuild# = %d\n"),
                          dvi.dwMajorVersion,
                          dvi.dwMinorVersion,
                          dvi.dwBuildNumber);

                switch(dvi.dwPlatformID) {
                case DLLVER_PLATFORM_WINDOWS:
                    lstrcat(szText, TEXT("Platform is Windows"));
                    break;

                case DLLVER_PLATFORM_NT:
                    lstrcat(szText, TEXT("Platform is Windows NT"));
                    break;

                default:
                    lstrcat(szText, TEXT("Platform is not defined"));
                    break;
                }
            } else {
                lstrcpy( szText,
                         TEXT("DllGetVersion Failed - Cannot determine DLL version."));
            }
        } else {
            lstrcpy( szText,TEXT("GetProcAddress Failed - The DLL does not implement DllGetVersion."));
        }
        CString s,vs;
        CModuleVersion ver;
        CString m_sModuleName(lpszDllName);
        if (ver.GetFileVersionInfo(m_sModuleName)) {
            vs.Format("%d.%d.%d.%d",
                HIWORD(ver.dwFileVersionMS),
                LOWORD(ver.dwFileVersionMS),
                HIWORD(ver.dwFileVersionLS),
                LOWORD(ver.dwFileVersionLS));
            s.Format("         Version: %s\n",vs);
            static LPCTSTR Keys[] = {
                _T("CompanyName"),
                _T("FileDescription"),
                _T("FileVersion"),
                _T("InternalName"),
                _T("LegalCopyright"),
                _T("OriginalFilename"),
                _T("ProductName"),
                _T("ProductVersion"),
                NULL
            };
            for (int i=0; Keys[i]; i++) {
                CString temp;
                temp.Format("%16s: %s\n", Keys[i], ver.GetValue(Keys[i]));
                s += temp;
            }
            if (v) printf("%s\n",vs);
            else   printf("%s",s);
        }
        FreeLibrary(hinstDll);
    } else {
        lstrcpy(szText, TEXT("Could not load the DLL"));
    }
    if (!v) printf("%s\n",szText);
}
void main(int argc,char **argv) {
    if (argc<=1) {
    Usage:
        printf("Usage: %s [-v] filename.dll\n",argv[0]);
        return;
    }
    if (argc<=2) {
        GetDllVersion(argv[1]);
    } else {
        if (0==stricmp(argv[1],"-v")||0==stricmp(argv[1],"/v")) {
            v=1;
            GetDllVersion(argv[2]);
        } else goto Usage;
    }
}