Parcourir la source

Add version number helper functions.

Gavin Lambert il y a 5 ans
Parent
commit
49fba2c0dc
6 fichiers modifiés avec 190 ajouts et 15 suppressions
  1. 32 0
      Files/ISPPBuiltins.iss
  2. 59 12
      ISHelp/isxfunc.xml
  3. 63 0
      Projects/ISPP/Help/ispp.xml
  4. 7 2
      Projects/ScriptFunc.pas
  5. 23 0
      Projects/ScriptFunc_R.pas
  6. 6 1
      whatsnew.htm

+ 32 - 0
Files/ISPPBuiltins.iss

@@ -168,6 +168,26 @@
 #define GetFileOriginalFilename(str FileName) GetStringFileInfo(FileName, ORIGINAL_FILENAME)
 #define GetFileProductVersion(str FileName) GetStringFileInfo(FileName, PRODUCT_VERSION)
 //
+// PackVersionComponents
+//
+// Packs individual version components into MS/LS values compatible with GetVersionNumbers.
+//
+#define PackVersionComponents(int Major, int Minor, int Rev, int Build, *MS, *LS) \
+  MS = (Major & 0xFFFF) << 16 | (Minor & 0xFFFF), \
+  LS = (Rev & 0xFFFF) << 16 | (Build & 0xFFFF), \
+  MS
+//
+// UnpackVersionComponents
+//
+// Unpacks individual version components from MS/LS values compatible with GetVersionNumbers.
+//
+#define UnpackVersionComponents(int MS, int LS, *Major, *Minor, *Rev, *Build) \
+  Major = MS >> 16, \
+  Minor = MS & 0xFFFF, \
+  Rev   = LS >> 16, \
+  Build = LS & 0xFFFF, \
+  Major
+//
 // ParseVersion
 //
 // Macro internally calls GetFileVersion function and parses string returned
@@ -189,6 +209,18 @@
     Build   = Int(Local[1]), \
   Local[0])
 //
+// ParseVersionPacked
+//
+// Macro internally calls GetFileVersion function and parses string returned
+// by that function (in form "0.0.0.0"). The version elements are then packed
+// back into the by-reference parameters MS and LS. Macro returns string
+// returned by GetFileVersion.
+//
+#define ParseVersionPacked(str FileName, *MS, *LS) \
+  Local[0] = ParseVersion(FileName, Local[1], Local[2], Local[3], Local[4]), \
+  PackVersionComponents(Local[1], Local[2], Local[3], Local[4], MS, LS), \
+  Local[0]
+//
 // EncodeVer
 //
 // Encodes given four version elements to a 32 bit integer number (8 bits for

+ 59 - 12
ISHelp/isxfunc.xml

@@ -1590,18 +1590,6 @@ end;</pre></example>
         <description><p>Generates a unique filename for a file in the specified path with the specified extension.</p></description>
       </function>
     </subcategory>
-    <subcategory>
-      <function>
-        <name>GetVersionNumbers</name>
-        <prototype>function GetVersionNumbers(const Filename: String; var VersionMS, VersionLS: Cardinal): Boolean;</prototype>
-        <description><p>Gets the file version numbers of the specified file.</p></description>
-      </function>
-      <function>
-        <name>GetVersionNumbersString</name>
-        <prototype>function GetVersionNumbersString(const Filename: String; var Version: String): Boolean;</prototype>
-        <description><p>Gets the file version numbers of the specified file, as a string.</p></description>
-      </function>
-    </subcategory>
     <subcategory>
       <function>
         <name>IsProtectedSystemFile</name>
@@ -1914,6 +1902,65 @@ end;</pre>
       </function>
     </subcategory>
   </category>
+  <category>
+    <description><p>File Version</p></description>
+    <subcategory>
+      <function>
+        <name>GetVersionNumbers</name>
+        <prototype>function GetVersionNumbers(const Filename: String; var VersionMS, VersionLS: Cardinal): Boolean;</prototype>
+        <description><p>Gets the file version numbers of the specified file.</p></description>
+        <seealso><p><link topic="isxfunc_PackVersionComponents">PackVersionComponents</link></p></seealso>
+      </function>
+      <function>
+        <name>GetVersionNumbersString</name>
+        <prototype>function GetVersionNumbersString(const Filename: String; var Version: String): Boolean;</prototype>
+        <description><p>Gets the file version numbers of the specified file, as a string.</p></description>
+      </function>
+    </subcategory>
+    <subcategory>
+      <function>
+        <name>PackVersionNumbers</name>
+        <prototype>function PackVersionNumbers(const VersionMS, VersionLS: Cardinal): Int64;</prototype>
+        <description><p>Packs version numbers (from <link topic="isxfunc_GetVersionNumbers">GetVersionNumbers</link>, ISPP's <tt>PackVersionComponents</tt>, or similar) into a single value.</p></description>
+        <remarks><p>You can directly compare two packed version numbers with the normal comparison operators (<tt>=</tt>, <tt>&lt;&gt;</tt>, <tt>&lt;</tt>, and <tt>&gt;</tt>).</p></remarks>
+        <seealso><p><link topic="isxfunc_PackVersionComponents">PackVersionComponents</link><br />
+<link topic="isxfunc_UnpackVersionNumbers">UnpackVersionNumbers</link><br />
+<link topic="isxfunc_VersionToStr">VersionToStr</link></p></seealso>
+      </function>
+      <function>
+        <name>PackVersionComponents</name>
+        <prototype>function PackVersionComponents(const Major, Minor, Revision, Build: Word): Int64;</prototype>
+        <description><p>Packs individual version components (from ISPP's <tt>ParseVersion</tt> or similar) into a single value.</p></description>
+        <remarks><p>You can directly compare two packed version numbers with the normal comparison operators (<tt>=</tt>, <tt>&lt;&gt;</tt>, <tt>&lt;</tt>, and <tt>&gt;</tt>).</p></remarks>
+        <seealso><p><link topic="isxfunc_PackVersionNumbers">PackVersionNumbers</link><br />
+<link topic="isxfunc_UnpackVersionComponents">UnpackVersionComponents</link></p></seealso>
+      </function>
+    </subcategory>
+    <subcategory>
+      <function>
+        <name>UnpackVersionNumbers</name>
+        <prototype>procedure UnpackVersionNumbers(const Version: Int64; var VersionMS, VersionLS: Cardinal);</prototype>
+        <description><p>Unpacks a packed version (for example, from <link topic="isxfunc_PackVersionNumbers">PackVersionNumbers</link>) into MS/LS numbers compatible with <link topic="isxfunc_GetVersionNumbers">GetVersionNumbers</link>.</p></description>
+        <seealso><p><link topic="isxfunc_UnpackVersionComponents">UnpackVersionComponents</link></p></seealso>
+      </function>
+      <function>
+        <name>UnpackVersionComponents</name>
+        <prototype>procedure UnpackVersionComponents(const Version: Int64; var Major, Minor, Revision, Build: Word);</prototype>
+        <description><p>Unpacks a packed version (for example, from <link topic="isxfunc_PackVersionComponents">PackVersionComponents</link>) into individual version components, suitable for display.</p></description>
+        <seealso><p><link topic="isxfunc_UnpackVersionNumbers">UnpackVersionNumbers</link></p></seealso>
+      </function>
+    </subcategory>
+    <subcategory>
+      <function>
+        <name>VersionToStr</name>
+        <prototype>function VersionToStr(const Version: Int64): String;</prototype>
+        <description><p>Gets the string (in "0.0.0.0" format) representing the given packed version.</p></description>
+        <remarks><p>This is intended mainly for logging/debugging purposes; when displaying versions to the user you should prefer using the version text resource directly rather than formatting the numeric version, as the application's preferred version formatting may be different from the default.</p></remarks>
+      </function>
+        <seealso><p><link topic="isxfunc_PackVersionNumbers">PackVersionNumbers</link><br />
+<link topic="isxfunc_PackVersionComponents">PackVersionComponents</link></p></seealso>
+    </subcategory>
+  </category>
   <category>
     <description><p>Registry</p></description>
     <subcategory>

+ 63 - 0
Projects/ISPP/Help/ispp.xml

@@ -1323,6 +1323,48 @@ The list of options is provided at the end of this topic.</para>
 					<para>&dim;, &redim;.</para>
 				</section>
 			</topic>
+			<topic id="PackVersionComponents">
+				<title>PackVersionComponents</title>
+				<section title="Prototype">
+					<pre>
+						<line>#define PackVersionComponents(int Major, int Minor, int Rev, int Build, *MS, *LS)</line>
+					</pre>
+				</section>
+				<description>
+					<para>Packs individual version components into MS/LS values compatible with <synel>GetVersionNumbers</synel>. The results are stored in by-reference parameters MS and LS.</para>
+					<pre>
+						<line>#define MyAppMS</line>
+						<line>#define MyAppLS</line>
+						<line>#expr PackVersionComponents(15, 2, 12345, 7, MyAppMS, MyAppLS)</line>
+					</pre>
+					<para>Declared in &builtins;.</para>
+				</description>
+				<section title="See also">
+					<para><synel><link href="ParseVersionPacked">ParseVersionPacked</link></synel>, <synel><link href="UnpackVersionComponents">UnpackVersionComponents</link></synel></para>
+				</section>
+			</topic>
+			<topic id="UnpackVersionComponents">
+				<title>UnpackVersionComponents</title>
+				<section title="Prototype">
+					<pre>
+						<line>#define UnpackVersionComponents(int MS, int LS, *Major, *Minor, *Rev, *Build)</line>
+					</pre>
+				</section>
+				<description>
+					<para>Unpacks individual version components from MS/LS values compatible with <synel>GetVersionNumbers</synel>. The results are stored in by-reference parameters Major, Minor, Rev, and Build.</para>
+					<pre>
+						<line>#define MyMajor</line>
+						<line>#define MyMinor</line>
+						<line>#define MyRev</line>
+						<line>#define MyBuild</line>
+						<line>#expr UnpackVersionComponents(MyAppMS, MyAppLS, MyMajor, MyMinor, MyRev, MyBuild)</line>
+					</pre>
+					<para>Declared in &builtins;.</para>
+				</description>
+				<section title="See also">
+					<para><synel><link href="PackVersionComponents">PackVersionComponents</link></synel></para>
+				</section>
+			</topic>
 			<topic id="ParseVersion">
 				<title>ParseVersion</title>
 				<section title="Prototype">
@@ -1335,6 +1377,27 @@ The list of options is provided at the end of this topic.</para>
           <para>Declared in &builtins;.</para>
 				</description>
 			</topic>
+			<topic id="ParseVersionPacked">
+				<title>ParseVersionPacked</title>
+				<section title="Prototype">
+					<pre>
+						<line>#define ParseVersionPacked(str FileName, *MS, *LS)</line>
+					</pre>
+				</section>
+				<description>
+					<para>Calls the <synel><link href="GetFileVersion">GetFileVersion</link></synel> function and parses the string returned by that function (in form "0.0.0.0"). The version elements are then packed back into the by-reference parameters MS and LS. Returns the string returned by GetFileVersion.</para>
+					<pre>
+						<line>#define MyAppMS</line>
+						<line>#define MyAppLS</line>
+						<line>#expr ParseVersionPacked("MyApp.exe", MyAppMS, MyAppLS)</line>
+					</pre>
+					<para>This can be combined at install-time with <synel>PackVersionNumbers</synel> to perform comparisons against installed files or registry versions.</para>
+					<para>Declared in &builtins;.</para>
+				</description>
+				<section title="See also">
+					<para><synel><link href="PackVersionComponents">PackVersionComponents</link></synel></para>
+				</section>
+			</topic>
 			<topic id="EncodeVer">
 				<title>EncodeVer</title>
 				<section title="Prototype">

+ 7 - 2
Projects/ScriptFunc.pas

@@ -271,10 +271,15 @@ const
   );
 
   { VerInfo }
-  VerInfoTable: array [0..1] of AnsiString =
+  VerInfoTable: array [0..6] of AnsiString =
   (
     'function GetVersionNumbers(const Filename: String; var VersionMS, VersionLS: Cardinal): Boolean;',
-    'function GetVersionNumbersString(const Filename: String; var Version: String): Boolean;'
+    'function GetVersionNumbersString(const Filename: String; var Version: String): Boolean;',
+    'function PackVersionNumbers(const VersionMS, VersionLS: Cardinal): Int64;',
+    'function PackVersionComponents(const Major, Minor, Revision, Build: Word): Int64;',
+    'procedure UnpackVersionNumbers(const Version: Int64; var VersionMS, VersionLS: Cardinal);',
+    'procedure UnpackVersionComponents(const Version: Int64; var Major, Minor, Revision, Build: Word);',
+    'function VersionToStr(const Version: Int64): String;'
   );
 
   { Windows }

+ 23 - 0
Projects/ScriptFunc_R.pas

@@ -1449,6 +1449,29 @@ begin
       Stack.SetBool(PStart, True);
     end else
       Stack.SetBool(PStart, False);
+  end else if Proc.Name = 'PACKVERSIONNUMBERS' then begin
+    Stack.SetInt64(PStart, Int64((UInt64(Stack.GetUInt(PStart-1)) shl 32) or Stack.GetUInt(PStart-2)));
+  end else if Proc.Name = 'PACKVERSIONCOMPONENTS' then begin
+    VersionNumbers.MS := (Stack.GetUInt(PStart-1) shl 16) or (Stack.GetUInt(PStart-2) and $FFFF);
+    VersionNumbers.LS := (Stack.GetUInt(PStart-3) shl 16) or (Stack.GetUInt(PStart-4) and $FFFF);
+    Stack.SetInt64(PStart, Int64((UInt64(VersionNumbers.MS) shl 32) or VersionNumbers.LS));
+  end else if Proc.Name = 'UNPACKVERSIONNUMBERS' then begin
+    VersionNumbers.MS := UInt64(Stack.GetInt64(PStart)) shr 32;
+    VersionNumbers.LS := UInt64(Stack.GetInt64(PStart)) and $FFFFFFFF;
+    Stack.SetUInt(PStart-1, VersionNumbers.MS);
+    Stack.SetUInt(PStart-2, VersionNumbers.LS);
+  end else if Proc.Name = 'UNPACKVERSIONCOMPONENTS' then begin
+    VersionNumbers.MS := UInt64(Stack.GetInt64(PStart)) shr 32;
+    VersionNumbers.LS := UInt64(Stack.GetInt64(PStart)) and $FFFFFFFF;
+    Stack.SetUInt(PStart-1, VersionNumbers.MS shr 16);
+    Stack.SetUInt(PStart-2, VersionNumbers.MS and $FFFF);
+    Stack.SetUInt(PStart-3, VersionNumbers.LS shr 16);
+    Stack.SetUInt(PStart-4, VersionNumbers.LS and $FFFF);
+  end else if Proc.Name = 'VERSIONTOSTR' then begin
+    VersionNumbers.MS := UInt64(Stack.GetInt64(PStart-1)) shr 32;
+    VersionNumbers.LS := UInt64(Stack.GetInt64(PStart-1)) and $FFFFFFFF;
+    Stack.SetString(PStart, Format('%u.%u.%u.%u', [VersionNumbers.MS shr 16,
+      VersionNumbers.MS and $FFFF, VersionNumbers.LS shr 16, VersionNumbers.LS and $FFFF]));
   end else
     Result := False;
 end;

+ 6 - 1
whatsnew.htm

@@ -32,7 +32,12 @@ For conditions of distribution and use, see <a href="https://jrsoftware.org/file
 <ul>
   <li>Added new [Run] and [UninstallRun] sections flag: <tt>dontlogparameters</tt>. If this flag is specified, the command line parameters for the program will not be included in the log file.</li>
   <li>Compiler IDE change: <a href="https://i.imgur.com/wHoJ3FG.png">Improved highlighting</a> for the [CustomMessages] and [Messages] sections.</li>
-  <li>Pascal Scripting change: <i>Fix:</i> Support function <tt>WizardSelectComponents</tt> now also updates component sizes and the current selection's required disk space.</li>
+  <li>Pascal Scripting changes:
+  <ul>
+    <li>Added several functions to pack/unpack version numbers to simplify comparisons: <tt>PackVersionNumbers</tt>, <tt>PackVersionComponents</tt>, <tt>UnpackVersionNumbers</tt>, <tt>UnpackVersionComponents</tt>, and <tt>VersionToStr</tt>.</li>
+    <li><i>Fix:</i> Support function <tt>WizardSelectComponents</tt> now also updates component sizes and the current selection's required disk space.</li>
+  </ul>
+  </li>
   <li>QuickStart Pack: Now registers the Inno Setup compiler path in the Inno Script Studio options so that it will find the Inno Setup compiler automatically. Required because Inno Script Studio doesn't officially support Inno Setup 6.</li> 
   <li>Minor tweaks.</li>
 </ul>