Comparing full versions numbers (xx.xx.xx.xx ? xx.xx.xx.xx)
Author: anonymous (talk, contrib) |
Description
This script compares two versions: lets name them needed and existing, and check if existing version greater than or equal to needed one.
Version is a string in format 'xx.xx.xx' where xx is integer numbers.
Number of sections (major version, minor version, etc.) in versions can differs in existing and needed versions.
Empty version means lowest version.
So it is possible to compare:
;needed | existing -> result ;'5.1' | '6.0.2800.106' -> 1 ;'6.0' | '6.0.2800.106' -> 1 ;'2.5' | '' -> 0 ;'7.2.5' | '6.0' -> 0 ;'7.2.5' | '8.0' -> 1 ;'5.1' | '5.1' -> 1 :) ;'2.8' | '2.50.4403.9' -> 1 (!!!) ;'2.80' | '2.50.4403.9' -> 0 (!!!)
Example
Your program need IE version 5.1 or higher and on user machine installed '6.0.2800.1106'
So you should call this:
Push "5.1" ;Needed verion of product Push $R0 ;Here you have to put existing version of product on target ;computer Call CompareVersions Pop $R0 ; If $R0 = '1' then existing version greater than or ;equval to a needed version
In our case we will have '1' in $R0, witch means "everithing is OK" :)
Note Added 9.06.2004
Dont forget, what versions compared as integer numbers!
Example from real life:
Checking MDAC version. (problem that in MDAC versions minor version is two digit number, some peoples (including me:) sometimes forget this)
So, you need MDAC v2.8
On system installed MDAC v2.50.4403.9
If you call
Push "2.8" Push "2.50.4403.9" Call CompareVersions Pop $R0
in $R0 will be 1 !!!! What's because 2.8 less then 2.50 (2 = 2 and 8 less than 50)
Solution is to check MDAC v2.80
Push "2.80" Push "2.50.4403.9" Call CompareVersions Pop $R0
in $R0 will be 0, thats just what we need :)
The Script
;----------------------------------------------------------------------------- ; CompareVersions ; input: ; top of stack = existing version ; top of stack-1 = needed version ; output: ; top of stack = 1 if current version => neded version, else 0 ; version is a string in format "xx.xx.xx.xx" (number of interger sections ; can be different in needed and existing versions) Function CompareVersions ; stack: existing ver | needed ver Exch $R0 Exch Exch $R1 ; stack: $R1|$R0 Push $R1 Push $R0 ; stack: e|n|$R1|$R0 ClearErrors loop: IfErrors VersionNotFound Strcmp $R0 "" VersionTestEnd Call ParseVersion Pop $R0 Exch Call ParseVersion Pop $R1 Exch IntCmp $R1 $R0 +1 VersionOk VersionNotFound Pop $R0 Push $R0 goto loop VersionTestEnd: Pop $R0 Pop $R1 Push $R1 Push $R0 StrCmp $R0 $R1 VersionOk VersionNotFound VersionNotFound: StrCpy $R0 "0" Goto end VersionOk: StrCpy $R0 "1" end: ; stack: e|n|$R1|$R0 Exch $R0 Pop $R0 Exch $R0 ; stack: res|$R1|$R0 Exch ; stack: $R1|res|$R0 Pop $R1 ; stack: res|$R0 Exch Pop $R0 ; stack: res FunctionEnd ;--------------------------------------------------------------------------------------- ; ParseVersion ; input: ; top of stack = version string ("xx.xx.xx.xx") ; output: ; top of stack = first number in version ("xx") ; top of stack-1 = rest of the version string ("xx.xx.xx") Function ParseVersion Exch $R1 ; version Push $R2 Push $R3 StrCpy $R2 1 loop: StrCpy $R3 $R1 1 $R2 StrCmp $R3 "." loopend StrLen $R3 $R1 IntCmp $R3 $R2 loopend loopend IntOp $R2 $R2 + 1 Goto loop loopend: Push $R1 StrCpy $R1 $R1 $R2 Exch $R1 StrLen $R3 $R1 IntOp $R3 $R3 - $R2 IntOp $R2 $R2 + 1 StrCpy $R1 $R1 $R3 $R2 Push $R1 Exch 2 Pop $R3 Exch 2 Pop $R2 Exch 2 Pop $R1 FunctionEnd ;---------------------------------------------------------------------------------------
If someone has any questions about code write here: woodman@e-pochta.kiev.ua. P.S. Sorry for poor english (my native language is russian). Where are not much comments left in scrip after publishing because of that :)