Added GetDllVersion /ProductVersion switch

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7310 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2021-08-30 00:06:25 +00:00
parent 52d6782447
commit 3a3d2202a7
10 changed files with 36 additions and 30 deletions

View file

@ -167,7 +167,7 @@ This command creates a temporary file. It puts its path into a define, named \e{
\S1{ppgetdllversion} !getdllversion
\c [/noerrors] [/packed] localfilename define_basename
\c [/noerrors] [/packed] [/productversion] localfilename define_basename
This is similar to \R{getdllversionlocal}{GetDLLVersionLocal}, only it stores the version number in defines and can therefore be used anywhere, not just inside functions and sections. /packed returns the information in two DWORDs.

View file

@ -61,7 +61,7 @@ Gets the Windows version as reported by GetVersionEx. WinVer.nsh is the preferre
\S2{getdllversion} GetDLLVersion
\c filename user_var(high dword output) user_var(low dword output)
\c [/ProductVersion] filename user_var(high dword output) user_var(low dword output)
Gets the version information from the DLL (or any other executable containing version information) in "filename". Sets the user output variables with the high and low dwords of version information on success; on failure the outputs are empty and the error flag is set. The following example reads the DLL version and copies a human readable version of it into $0:
@ -74,7 +74,7 @@ Gets the version information from the DLL (or any other executable containing ve
\S2{getdllversionlocal} GetDLLVersionLocal
\c localfilename user_var(high dword output) user_var(low dword output)
\c [/ProductVersion] localfilename user_var(high dword output) user_var(low dword output)
This is similar to \R{getdllversion}{GetDLLVersion}, only it acts on the system building the installer (it actually compiles into two \R{StrCpy}{StrCpy} commands). Sets the two output variables with the DLL version information of the DLL on the build system. Use \R{ppgetdllversion}{!getdllversion} if you need to use the values with \R{viproductversion}{VIProductVersion}.

View file

@ -18,6 +18,8 @@ Released on ???? ??th, 20??
\b Added \cw{$USER..} and \cw{$COMMON..} alias constants
\b Added GetDllVersion /ProductVersion switch
\b Added \R{getwinver}{GetWinVer} instruction
\b Disallow start maximized mode

View file

@ -334,7 +334,7 @@ static bool GetTLBVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low
}
#endif //~ !_WIN32
bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low)
bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low, bool NotUsed)
{
bool found = false;
#if defined(_WIN32) && !defined(NSIS_GETTLBVERSION_FORCEINTERNAL)
@ -345,11 +345,11 @@ bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low)
return found;
}
static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD &high, DWORD &low)
static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD &high, DWORD &low, bool Product)
{
bool found = false;
LANGID anylangid = CResourceEditor::ANYLANGID;
unsigned long fileSize;
unsigned long fileSize, fieldofs = Product ? 2 : 0;
void*pFileData = alloc_and_read_file(filepath, fileSize);
if (!pFileData) return false;
try
@ -369,7 +369,7 @@ static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD &high, DWORD &low)
VS_FIXEDFILEINFO *verinfo = (VS_FIXEDFILEINFO*)(resdata + len);
if (ressize >= len + sizeof(VS_FIXEDFILEINFO) && verinfo->dwSignature == FIX_ENDIAN_INT32(VS_FFI_SIGNATURE))
{
high = FIX_ENDIAN_INT32(verinfo->dwFileVersionMS), low = FIX_ENDIAN_INT32(verinfo->dwFileVersionLS);
high = FIX_ENDIAN_INT32((&verinfo->dwFileVersionMS)[fieldofs]), low = FIX_ENDIAN_INT32((&verinfo->dwFileVersionLS)[fieldofs]);
found = true;
}
}
@ -383,11 +383,11 @@ static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD &high, DWORD &low)
return found;
}
static bool GetDLLVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low)
static bool GetDLLVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low, bool Product)
{
bool found = false;
#ifdef _WIN32
TCHAR path[1024], *name;
TCHAR path[1024], *name, fieldofs = Product ? 2 : 0;
path[0] = 0;
GetFullPathName(filepath, 1024, path, &name);
@ -401,7 +401,7 @@ static bool GetDLLVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low
VS_FIXEDFILEINFO *pvsf;
if (GetFileVersionInfo(path, 0, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &valSize))
{
high = pvsf->dwFileVersionMS, low = pvsf->dwFileVersionLS;
high = (&pvsf->dwFileVersionMS)[fieldofs], low = (&pvsf->dwFileVersionLS)[fieldofs];
found = true;
}
free(buf);
@ -420,11 +420,11 @@ typedef struct tagMINI_IMAGE_VXD_HEADER {
} MINI_IMAGE_VXD_HEADER, *PMINI_IMAGE_VXD_HEADER;
#pragma pack(pop)
static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low)
static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low, bool Product)
{
bool found = false;
FILEVIEW map;
char *filedata = create_file_view_readonly(filepath, map);
char *filedata = create_file_view_readonly(filepath, map), fieldofs = Product ? 2 : 0;
if (filedata)
{
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) filedata;
@ -452,7 +452,7 @@ static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low)
VS_FIXEDFILEINFO *pFFI = MKPTR(VS_FIXEDFILEINFO*, pVSVI, 2 + 2 + 16);
if (LE2HE32(pFFI->dwSignature) == 0xFEEF04BD)
{
high = LE2HE32(pFFI->dwFileVersionMS), low = LE2HE32(pFFI->dwFileVersionLS);
high = LE2HE32((&pFFI->dwFileVersionMS)[fieldofs]), low = LE2HE32((&pFFI->dwFileVersionLS)[fieldofs]);
found = true;
}
}
@ -465,11 +465,11 @@ static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low)
return found;
}
bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low)
bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low, bool Product)
{
bool result = GetDLLVersionUsingAPI(filepath, high, low);
if (!result) result = GetDLLVersionUsingRE(filepath, high, low);
if (!result) result = GetDLLVersionFromVXD(filepath, high, low);
bool result = GetDLLVersionUsingAPI(filepath, high, low, Product);
if (!result) result = GetDLLVersionUsingRE(filepath, high, low, Product);
if (!result) result = GetDLLVersionFromVXD(filepath, high, low, Product);
return result;
}

View file

@ -26,9 +26,9 @@ signed char GetExeType(const void*pData, size_t Size);
signed char GetExeType(const TCHAR*filepath);
FILE* MSTLB_fopen(const TCHAR*filepath, size_t*pResId = 0);
bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low);
bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low, bool NotUsed = false);
bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low);
bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low, bool Product = false);
typedef struct GENERICIMAGEINFO {
UINT32 Width, Height;

View file

@ -987,8 +987,8 @@ static int NSISCALL ExecuteEntry(entry *entry_)
if ( ((BOOL(WINAPI*)(LPCTSTR,DWORD,DWORD,LPVOID))gfvi)(buf1,0,s1,b1)
&& ((BOOL(WINAPI*)(LPCVOID,LPCTSTR,LPVOID*,UINT*))vqv)(b1,_T("\\"),(void*)&pvsf1,&uLen) )
{
myitoa(highout,pvsf1->dwFileVersionMS);
myitoa(lowout,pvsf1->dwFileVersionLS);
myitoa(highout,(&pvsf1->dwFileVersionMS)[parm3]);
myitoa(lowout,(&pvsf1->dwFileVersionLS)[parm3]);
exec_error--;
}

View file

@ -130,7 +130,7 @@ enum
#endif
#ifdef NSIS_SUPPORT_GETDLLVERSION
EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout]
EW_GETDLLVERSION, // GetDLLVersion: 4 [file highout lowout fixedoffset]
#endif
#ifdef NSIS_SUPPORT_ACTIVEXREG

View file

@ -4022,8 +4022,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_GETDLLVERSIONLOCAL:
{
const TCHAR*cmdname=_T("GetDLLVersionLocal");
DWORD low, high;
if (!GetDLLVersion(line.gettoken_str(1),high,low))
DWORD low, high, prod = line.gettoken_enum(1, _T("/ProductVersion\0")) == 0 ? 2 : 0;
if (prod) line.eattoken();
if (!GetDLLVersion(line.gettoken_str(1),high,low,!!prod))
{
ERROR_MSG(_T("%") NPRIs _T(": error reading version info from \"%") NPRIs _T("\"\n"),cmdname,line.gettoken_str(1));
return PS_ERROR;
@ -4190,7 +4191,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return add_entry(&ent);
case TOK_GETWINVER:
{
int k = line.gettoken_enum(2, _T("major\0minor\0build\0servicepack\0product\0ntddimajmin")), cb = 0, ofs = 0;
int k = line.gettoken_enum(2, _T("major\0minor\0build\0servicepack\0product\0ntddimajmin\0")), cb = 0, ofs = 0;
switch(k)
{
case 0: cb = 1, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVMaj); break;
@ -4235,6 +4236,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_GETDLLVERSION:
#ifdef NSIS_SUPPORT_GETDLLVERSION
ent.which=EW_GETDLLVERSION;
if ((ent.offsets[3]=line.gettoken_enum(1, _T("/ProductVersion\0")) == 0 ? 2 : 0)) line.eattoken();
ent.offsets[0]=GetUserVarIndex(line, 2);
ent.offsets[1]=GetUserVarIndex(line, 3);
ent.offsets[2]=add_string(line.gettoken_str(1));

View file

@ -607,17 +607,19 @@ int CEXEBuild::pp_getversion(int which_token, LineParser&line)
{
const bool tlb = TOK_P_GETTLBVERSION == which_token;
const TCHAR *cmdname = tlb ? _T("!gettlbversion") : _T("!getdllversion"), *path;
DWORD ti = 1, flags = tlb ? PPGVHF_TLB : 0, low, high;
DWORD ti = 1, flags = tlb ? PPGVHF_TLB : 0, low, high, prod = 0;
for (;; ++ti)
{
if (!_tcsicmp(line.gettoken_str(ti), _T("/noerrors")))
flags |= PPGVHF_NOERRORS;
else if (!_tcsicmp(line.gettoken_str(ti), _T("/packed")))
flags |= PPGVHF_PACKED;
else if (!_tcsicmp(line.gettoken_str(ti), _T("/productversion")))
++prod;
else
break;
}
if ((tlb ? GetTLBVersion : GetDLLVersion)(path = line.gettoken_str(ti), high, low)) flags |= PPGVHF_VALID;
if ((tlb ? GetTLBVersion : GetDLLVersion)(path = line.gettoken_str(ti), high, low, !!prod)) flags |= PPGVHF_VALID;
return pp_getversionhelper(cmdname, path, line.gettoken_str(ti+1), high, low, flags);
}

View file

@ -50,8 +50,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_CHANGEUI,_T("ChangeUI"),2,0,_T("(all|dlg_id) ui_file.exe"),TP_GLOBAL},
{TOK_CLEARERRORS,_T("ClearErrors"),0,0,_T(""),TP_CODE},
{TOK_COMPTEXT,_T("ComponentText"),0,3,_T("[component_page_description] [component_subtext1] [component_subtext2]"),TP_PG},
{TOK_GETDLLVERSION,_T("GetDLLVersion"),3,0,_T("filename $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_GETDLLVERSIONLOCAL,_T("GetDLLVersionLocal"),3,0,_T("localfilename $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_GETDLLVERSION,_T("GetDLLVersion"),3,1,_T("[/ProductVersion] filename $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_GETDLLVERSIONLOCAL,_T("GetDLLVersionLocal"),3,1,_T("localfilename $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_GETFILETIME,_T("GetFileTime"),3,0,_T("file $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_GETFILETIMELOCAL,_T("GetFileTimeLocal"),3,0,_T("localfile $(user_var: high output) $(user_var: low output)"),TP_CODE},
{TOK_COPYFILES,_T("CopyFiles"),2,3,_T("[/SILENT] [/FILESONLY] source_path destination_path [total_size_in_kb]"),TP_CODE},
@ -306,7 +306,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_P_TEMPFILE,_T("!tempfile"),1,0,_T("symbol"),TP_ALL},
{TOK_P_DELFILE,_T("!delfile"),1,1,_T("[/nonfatal] file"),TP_ALL},
{TOK_P_APPENDFILE,_T("!appendfile"),2,2,_T("[/CHARSET=<") TSTR_OUTPUTCHARSET _T(">] [/RAWNL] file appended_line"),TP_ALL},
{TOK_P_GETDLLVERSION,_T("!getdllversion"),2,2,_T("[/noerrors] [/packed] localfilename define_basename"),TP_ALL},
{TOK_P_GETDLLVERSION,_T("!getdllversion"),2,3,_T("[/noerrors] [/packed] [/productversion] localfilename define_basename"),TP_ALL},
{TOK_P_GETTLBVERSION,_T("!gettlbversion"),2,2,_T("[/noerrors] [/packed] localfilename define_basename"),TP_ALL},
{TOK_P_SEARCHPARSESTRING,_T("!searchparse"),3,-1,_T("[/ignorecase] [/noerrors] [/file] source_string_or_file substring OUTPUTSYM1 [substring [OUTPUTSYM2 [substring ...]]]"),TP_ALL},