バージョンリソース文字列の取得

解説


 EXEファイルなどに格納されているバージョンリソースからデータを取り出すための クラス。
 複数言語のバージョンリソースが格納されている場合は、もっとも先に見つかった言語 のものを返す。本当なら日本語、ニュートラル、英語...の順序で検索したほうがいい のかもしれない...



使用例


	CAtlString		strData;
	CDnpFileVersion	cInfo;

	cInfo.Load("C:\\WINDOWS\\system32\\cmd.exe");
	cInfo.GetValue("FileDescription",strData);

	cInfo.GetComments(strData);
	cInfo.GetInternalName(strData);
	cInfo.GetProductName(strData);
	cInfo.GetCompanyName(strData);
	cInfo.GetLegalCopyright(strData);
	cInfo.GetProductVersion(strData);
	cInfo.GetFileDescription(strData);
	cInfo.GetLegalTrademarks(strData);
	cInfo.GetPrivateBuild(strData);
	cInfo.GetFileVersion(strData);
	cInfo.GetOriginalFilename(strData);
	cInfo.GetSpecialBuild(strData);




ソースコード



#include "atlstr.h"
#pragma	comment(lib,"Version.lib")

class	CDnpFileVersion
{
	struct LANGANDCODEPAGE
	{
	  WORD wLanguage;
	  WORD wCodePage;
	};


	BYTE*				_pVersionInfo;
	LANGANDCODEPAGE*	_pTranslation;
	UINT				_nTranslationLen;

	void	Destroy(void)
	{
		if(_pVersionInfo)
			delete	_pVersionInfo;
		_pVersionInfo = NULL;
		_pTranslation = NULL;
		_nTranslationLen = 0;
	}

public:
	CDnpFileVersion()
	{
		_pVersionInfo = NULL;
		_pTranslation = NULL;
		_nTranslationLen = 0;
	}

	~CDnpFileVersion()
	{
		Destroy();
	}


	bool	Load(LPCTSTR pszFile)
	{
		BOOL	ret;
		DWORD	dwSize;
		BYTE*	pData;
		BYTE*	pResult;
		UINT	nLen;

		Destroy();
		dwSize = ::GetFileVersionInfoSize(pszFile,NULL);
		if(dwSize == 0)
			return	false;

		pData = new BYTE[dwSize];
		if(pData == NULL)
			return	false;

		ret = ::GetFileVersionInfo(pszFile,NULL,dwSize,pData);

		if(ret)
			ret = ::VerQueryValue(pData,_T("\\VarFileInfo\\Translation"),(void**)&pResult,&nLen); 

		if(ret == FALSE)
		{
			delete	pData;
			return	false;
		}

		_pVersionInfo = pData;
		_pTranslation = (LANGANDCODEPAGE*)pResult;
		_nTranslationLen = nLen;

		return	true;
	}

	bool	Unload(void)
	{
		Destroy();
		return	true;
	}


	bool	GetValue(LPCTSTR pszBlockName,CAtlString& strValue)
	{
		int			i;
		int			nSize;
		BOOL		ret;
		UINT		nLen;
		BYTE*		pData;
		CAtlString	strPath;

		strValue = _T("");

		if(_pVersionInfo == NULL || _pTranslation == NULL)
			return	false;

		nSize = _nTranslationLen / sizeof(LANGANDCODEPAGE);

		for(i = 0; i < nSize; i++)
		{
			strPath.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),_pTranslation[i].wLanguage,_pTranslation[i].wCodePage,pszBlockName);
			ret = ::VerQueryValue(_pVersionInfo,(LPTSTR)(LPCTSTR)strPath,(void**)&pData,&nLen);
			if(ret == FALSE)
				continue;

			strValue = (TCHAR*)pData;
			return	true;
		}

		return	false;
	}


	bool	GetComments(CAtlString& strValue)
	{
		return	GetValue(_T("Comments"),strValue);
	}

	bool	GetInternalName(CAtlString& strValue)
	{
		return	GetValue(_T("InternalName"),strValue);
	}

	bool	GetProductName(CAtlString& strValue)
	{
		return	GetValue(_T("ProductName"),strValue);
	}

	bool	GetCompanyName(CAtlString& strValue)
	{
		return	GetValue(_T("CompanyName"),strValue);
	}

	bool	GetLegalCopyright(CAtlString& strValue)
	{
		return	GetValue(_T("LegalCopyright"),strValue);
	}

	bool	GetProductVersion(CAtlString& strValue)
	{
		return	GetValue(_T("ProductVersion"),strValue);
	}

	bool	GetFileDescription(CAtlString& strValue)
	{
		return	GetValue(_T("FileDescription"),strValue);
	}

	bool	GetLegalTrademarks(CAtlString& strValue)
	{
		return	GetValue(_T("LegalTrademarks"),strValue);
	}

	bool	GetPrivateBuild(CAtlString& strValue)
	{
		return	GetValue(_T("PrivateBuild"),strValue);
	}

	bool	GetFileVersion(CAtlString& strValue)
	{
		return	GetValue(_T("FileVersion"),strValue);
	}

	bool	GetOriginalFilename(CAtlString& strValue)
	{
		return	GetValue(_T("OriginalFilename"),strValue);
	}

	bool	GetSpecialBuild(CAtlString& strValue)
	{
		return	GetValue(_T("SpecialBuild"),strValue);
	}
};


カテゴリー「VC++ TIPS」 のエントリー