//--------------------------------------------------------------------------- /* TExeVer is a FREEWARE Component and therefore can be used freely. Please let me know if you find any bugs in it. I can be reached at imranh@summitdata.com USAGE: There are about 14 readonly properties of this component that can be accessed at run time. All of them are readonly CompanyName FileDescription FileVersion InternalName LegalCopyright LegalTrademarks OriginalFilename ProductName ProductVersion Comments MajorVersion MinorVersion Release Build */ #include #pragma hdrstop #include "ExeVer.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // ValidCtrCheck is used to assure that the components created do not have // any pure virtual functions. // static inline void ValidCtrCheck(TExeVersion *) { new TExeVersion(NULL); } //--------------------------------------------------------------------------- __fastcall TExeVersion::TExeVersion(TComponent* Owner) : TComponent(Owner) { } //--------------------------------------------------------------------------- namespace Exever { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TExeVersion)}; RegisterComponents("Samples", classes, 0); } } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetCompanyName(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"CompanyName",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetMajorVersion(){ AnsiString answer; answer = GetFileVersion(); answer = answer.SubString(0, answer.Pos(".")); return answer; } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetMinorVersion(){ AnsiString answer; char szBuf[25]; char* p; answer = GetFileVersion(); strcpy(szBuf, answer.c_str()); p = strtok(szBuf, "."); p = strtok(NULL, "."); answer = p; return answer; } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetRelease(){ AnsiString answer; char szBuf[25]; char* p; answer = GetFileVersion(); strcpy(szBuf, answer.c_str()); p = strtok(szBuf, "."); p = strtok(NULL, "."); p = strtok(NULL, "."); answer = p; return answer; } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetBuild(){ AnsiString answer; char szBuf[25]; char* p; answer = GetFileVersion(); strcpy(szBuf, answer.c_str()); p = strtok(szBuf, "."); p = strtok(NULL, "."); p = strtok(NULL, "."); p = strtok(NULL, "."); answer = p; return answer; } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetFileDescription(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"FileDescription",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetFileVersion(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"FileVersion",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetInternalName(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"InternalName",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetLegalCopyright(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"LegalCopyright",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetLegalTrademarks(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"LegalTrademarks",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetOriginalFilename(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"OriginalFilename",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetProductName(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"ProductName",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetProductVersion(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"ProductVersion",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- AnsiString __fastcall TExeVersion::GetComments(){ char c[MAX_PATH]; AnsiString buf; DWORD dwver; GetFileVersionField(Application->ExeName.c_str(),"Comments",c,MAX_PATH,&dwver); buf = c; return buf.Trim(); } //--------------------------------------------------------------------------- //This function actually gets the information from the file. //I did not write this function. Someone posted on a newsgroup. //Can't recall his/her name. int __fastcall TExeVersion::GetFileVersionField(char *fn, char *info, char *ret, int len, DWORD *dwver) { DWORD hVersion; if (dwver!=NULL) *dwver=0; DWORD vis=GetFileVersionInfoSize(fn,&hVersion); if (vis==0) return 0; void *vData; vData=(void *)new char[(UINT)vis]; if (!GetFileVersionInfo(fn,hVersion,vis,vData)){ delete vData; return 0; } char vn[100]; strcpy(vn,"\\VarFileInfo\\Translation"); LPVOID transblock; UINT vsize; BOOL res = VerQueryValue(vData,vn,&transblock,&vsize); if (!res) { delete vData; return 0; } // Swap the words so wsprintf will print the lang-charset in the correct format. *(DWORD *)transblock = MAKELONG(HIWORD(*(DWORD *)transblock), LOWORD(*(DWORD *)transblock)); wsprintf(vn,"\\StringFileInfo\\%08lx\\%s",*(DWORD *)transblock,info); char *ver; res=VerQueryValue(vData,vn,(LPVOID*)&ver,&vsize); if (!res) {delete vData; return 0;} int vlen=strlen(ver); if (ret!=NULL) { int clen=vlen+1; if (clen>=len-1) clen=len-1; // ie. we'll try to copy the \0 in vData, but we'll leave space // for the thing. for (int i=0; i < clen; i++) ret[i]=ver[i]; ret[len-1]=0; } // The following code converts a string like 1.0 or 1.1.5 into // a DWORD where the first digit is the leading byte, and so on. // It discards version numbers greater than 255, and discards // anything after the fourth version sub-part. if (dwver!=NULL) { DWORD v=0; BOOL atend=FALSE; char *first=ver; char *next=first; int places=0; while (!atend) { while (*next!=0 && *next!='.' && *next!=',') next++; if (*next==0) atend=TRUE; *next=0; int i; int res=sscanf(first,"%i",&i); if (res==0) atend=TRUE; else {v=(v<<8)|(i&255); places++;} next++; first=next; if (places==4) atend=TRUE; } for (int i=places; i < 4; i++) v=v<<8; *dwver=v; } delete vData; // return vlen; }