2013年4月17日 星期三

使用GetFileVersionInfo來取得程式的版本資訊

延續前一篇使用VC6與VC2010在Resource欄位的差異,透過GetFileVersionInfo來取得程式中,有關版本資訊,就可以比較出VC6與VC2010在Resource檔的差異。
*.CPP程式碼。
BOOL GetFileVersion()
{
 char cPath[MAX_PATH], cSubBlock[MAX_PATH];
 DWORD dwHandle, dwInfoSize, dwTrans;
 UINT uTranslate = 0, uBytes = 0;
 DWORD *dwTranslation = NULL;
 CHAR *cpBuffer = NULL;

 //Find file module path
 if(!GetModuleFileName(AfxGetInstanceHandle(), cPath, sizeof(cPath)))
 {
  printf("ERROR : Can't find resource version table path.\n");
  return FALSE;
 }

 //Get file version size 
 dwInfoSize = GetFileVersionInfoSize(cPath, &dwHandle);
 if(dwInfoSize == 0)
 {
  printf("ERROR : The file resource version size is error.\n");
  return FALSE;
 }

 //Allocate buffer and retrieve version information 
 char *cpInfoBuf = new char[dwInfoSize];
 if(!cpInfoBuf)
 {
  return FALSE;
 }

 if(!GetFileVersionInfo(cPath, 0, dwInfoSize, cpInfoBuf))
 {
  delete [] cpInfoBuf;
  return FALSE;
 }   

 //Get the language setting first 
 if(!VerQueryValue(cpInfoBuf, _TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&dwTranslation, &uTranslate))
 {
  delete [] cpInfoBuf;
  return FALSE;
 }

 if(*dwTranslation == NULL)
 {
  delete [] cpInfoBuf;
  return FALSE;
 }

 dwTrans = MAKELONG(HIWORD (dwTranslation[0]), LOWORD (dwTranslation[0]));
 // Read the file description for each language and code page.
 CHAR *szpVersion[] = { "CompanyName", 
       "FileVersion",
       "LegalCopyright",
       "PrivateBuild", 
       "Comments",
       "InternalName",
       "ProductName",
       "ProductVersion",
       "FileDescription",
       "LegalTrademarks",
       "OriginalFilename",
       "SpecialBuild" };


 for (int i = 0 ; i < VERSIONCOUNT ; i++)
 {
  sprintf( cSubBlock, _TEXT("\\StringFileInfo\\%08lx\\%s"), dwTrans, szpVersion[i]); 
  if (!VerQueryValue(cpInfoBuf, cSubBlock, (LPVOID* )&cpBuffer, &uBytes))
  {
   //printf("Warning : The file is no version information.\n");
   //return FALSE;
   m_csRCVersionInfo[i] = "";
   continue;
  }
  m_csRCVersionInfo[i] = cpBuffer;
 }  

 delete [] cpInfoBuf;
 dwTranslation = NULL;
 cpBuffer = NULL;

 return TRUE;
}
*.h程式碼。
#pragma  comment(lib, "VERSION.LIB")

enum { 
 COMPANYNAME,
 FILESVERSION,
 LEGALCOPYRIGHT,
 PRIVATEBUILD,
 COMMENTS,
 INTERNALNAME,
 PRODUCTNAME,
 PRODUCTSVERSION,
 FILEDESCRIPTION,
 LEGALTRADEMARKS,
 ORIGINALFILENAME,
 SPECIALBUILD,
 VERSIONCOUNT
};

CString m_csRCVersionInfo[12];