Skip to content
⌘ NSIS Forum Archive

How to parse text version number

6 posts

1marc1#

How to parse text version number

Hi,

I am writing an installer for a piece of Windows software that requires a certain minimum version of Ruby (along with some Ruby Gems) to be installed on the target machine. I have been reading various tutorials and got lots of useful stuff from example files, but I am still stuck on how to process this elegantly using NSIS.

Here is what I would like NSIS to accomplish:

1. Check if Ruby is installed (by executing `ruby --version` and interpreting the output).
1a. If Ruby is not installed, then NSIS will need to install a compatible version (by showing an NSIS RO section for Ruby).
1b. If Ruby is installed, then find out which version.
1bi. If version >= 2.3, then no need to do anything further (by not showing/executing the Ruby section).
1bii. If version < 2.3, then install a compatible version (by showing an NSIS RO section for Ruby).

2. Check if MyGem is installed (by executing `gem list --local MyGem` and interpreting the output).
2a. If MyGem is not installed, then NSIS will need to install it (by showing an NSIS RO section for MyGem, which executes `gem install MyGem`, which will retrieve the gem from the internet).
2b. If MyGem is installed, then find out which version.
2bi. If version >= 0.5.2, then no need to do anything further.
2bii. If version < 0.5.2, then install the latest version (by showing an NSIS RO section for MyGem, which executes `gem install MyGem`, which will retrieve the gem from the internet).

Here is the part of my NSIS script that should check the version number (just focussing on Ruby itself for now):


Function InitComponents
ExpandEnvStrings $0 %COMSPEC%
nsExec::ExecToStack '"$0" /C ruby --version'

; If Ruby is installed, the expected output contains something like this:
; ruby 2.4.3p205 (2017-12-14 revision 61247) [x64-mingw32]

pop $0
pop $1

${StrContains} $2 "ruby " "$1"
StrCmp $2 "" notfound
MessageBox MB_OK 'Ruby was found, not installing it'
Goto done
notfound:
MessageBox MB_OK 'Did not find string "ruby ". Therefore Ruby should be installed.'
SectionSetText ${SectionRuby} "Ruby"
${SelectSection} ${SectionRuby}
done:
FunctionEnd

The above code works in that it will properly tell me that it will install Ruby or not. The problem is, I cannot seem to work out how to do the version check. For the equivalent Linux installer, I have used awk to concatenate the first and second number of the version ("2.4.3p205", resulting in the number 24) and compare that to the number 23 (representing the minimum version 2.3).

Any tips on how I can accomplish the same or similar with NSIS?

Thank you.
1marc1#
Anders,

I saw that as well after posting the question. However, I am stuck trying to figure out how to actually extract the version number part from the output string. Consider that I have one of the following pieces of text in a variable:

1. This is a bit of text and somewhere in this text is the ruby version number written as ruby 2.4.3p205 (2017-12-14 revision 61247) [x64-mingw32], followed by more text.

2. ruby 2.4.3p205 (2017-12-14 revision 61247) [x64-mingw32]

Which function would I use to get to "2.4.3p205" or (better) "2.4.3"?

Marc.
r2du-soft#
try this:
its work for me on windows 10 x64 with ruby Version 2.6.3

Unicode true

!include "X64.nsh"
!include "LogicLib.nsh"

Var Ruby_Display_Version

Section

ClearErrors
EnumRegKey $Ruby_Display_Version HKLM "SOFTWARE\RubyInstaller\MRI" $0
${If} ${Errors}
MessageBox MB_OK "Error to read Ruby Version"
Abort
${EndIf}



${IF} $Ruby_Display_Version S>= "2.6.2"
MessageBox MB_OK "$Ruby_Display_Version"
MessageBox MB_OK "Everything is OK"
${ELSE}
MessageBox MB_OK "$Ruby_Display_Version"
MessageBox MB_OK "Youneed newer Version of Ruby"
${ENDIF}

SectionEnd
You most test on other ruby versions...
r2du-soft#
also you can find installed ruby version like this:

Unicode true

!include "X64.nsh"
!include "LogicLib.nsh"
!include "StrRep.nsh"


Var Ruby_Informations
Var Ruby_RegistryKey_Address
Var Ruby_Display_Version


Function InitComponents

ileOpen $9 "c:\Ruby_Informations.bat" w
FileWrite $9 "Ruby.exe -v>c:\Ruby_Informations.Log"
FileClose $9 ;Closes the filled file

;------------------------
ShellExecAsUser::ShellExecAsUser "open" "c:\Ruby_Informations.bat"
Sleep 1000
CK_1:
${IFNOT} ${FileExists} "c:\Ruby_Informations.Log"
Sleep 1000
Goto CK_1
${EndIF}
;------------------------
FileOpen $4 "c:\Ruby_Informations.Log" r
FileRead $4 $Ruby_Informations
FileClose $4
;------------------------
Delete /REBOOTOK "c:\Ruby_Informations.Log"
Delete /REBOOTOK "c:\Ruby_Informations.bat"
;------------------------

${StrRep} '$Ruby_Informations' '$Ruby_Informations' '$\r$\n' ''
;MessageBox MB_OK "$Ruby_Informations"


StrCpy $R1 "$Ruby_Informations" 5
${IF} $R1 = "ruby "
MessageBox MB_OK "Ruby was found, not installing it."

	;-----------------------------------
	StrCpy $R1 "$Ruby_Informations" 3 5
	;-----------------------------------
	;-----------------------------------
	StrCpy $R2 "$Ruby_Informations" "" -12
	StrCpy $R2 $R2 11
	;-----------------------------------
	
	StrCpy $Ruby_RegistryKey_Address "RubyInstaller-$R1-$R2_is1"
	;MessageBox MB_OK "$Ruby_RegistryKey_Address"
	
	ReadRegStr $Ruby_Display_Version HKCU 'Software\Microsoft\Windows\CurrentVersion\Uninstall\$Ruby_RegistryKey_Address' "DisplayVersion"	
	MessageBox MB_OK "$Ruby_Display_Version"
	

${Else}
MessageBox MB_OK 'Did not find string "ruby ". Therefore Ruby should be installed.'
;Call function of install ruby
${ENDIf}

Quit


FunctionEnd


Section
Call InitComponents
SectionEnd
1marc1#
r2du-soft,

Thank you for your suggestions. I ended up adapting parts of your second idea.

Marc.