Old 7th April 2006, 14:00   #1
Kypec
Member
 
Kypec's Avatar
 
Join Date: Jul 2002
Location: Slovakia
Posts: 54
Question How to detect Windows Installer version?

Hi guys,

is there some easy way to detect which version
of M$ Windows Installer is present on user's system?
What I want to achieve is this:
I have created my NSIS installer which detects the version
of .NET Framework (via DotNET.nsh) and runs dotnetfx.exe externally if needed.
The problem is, however, that this package requires another M$ prerequisite to be there => WindowsInstaller-KB893803-v2-x86.exe
How can one find out whether this MSI 3.1 is already installed on user's system?
Kypec is offline   Reply With Quote
Old 7th April 2006, 14:18   #2
galil
Member
 
Join Date: Jan 2003
Posts: 83
Do a GetDLLVersion (as described in the manual or here: http://nsis.sourceforge.net/GetDllVe...mand_Explained) on "$SYSDIR\msi.dll"
You probably don't need to check release & build parts though.
galil is offline   Reply With Quote
Old 7th April 2006, 14:19   #3
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
You can check the version of $SYSDIR\msi.dll using GetDLLVersion. It's hardly the official method, but I couldn't find anything about it in MSDN.

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 7th April 2006, 14:40   #4
iceman_k
NSIS Dev
 
iceman_k's Avatar
 
Join Date: Feb 2003
Location: Boston, MA, U.S.A.
Posts: 455
Quote:
Originally posted by kichik
You can check the version of $SYSDIR\msi.dll using GetDLLVersion. It's hardly the official method, but I couldn't find anything about it in MSDN.
It's probably the closest thing to an official method that you are going to get. It's what the Windows Installer team says you should do.
http://blogs.msdn.com/windows_instal...09/458528.aspx

Cheers,
Iceman_K

EclipseNSIS - An NSIS IDE for the Eclipse Platform | My contributions to the wiki
iceman_k is offline   Reply With Quote
Old 7th April 2006, 14:48   #5
Kypec
Member
 
Kypec's Avatar
 
Join Date: Jul 2002
Location: Slovakia
Posts: 54
Many thanks to all of you for quick replies.
I'll try what you are suggesting.
Kypec is offline   Reply With Quote
Old 17th April 2006, 13:24   #6
panccio
Guest
 
Posts: n/a
i thank to all too..
  Reply With Quote
Old 10th July 2006, 12:05   #7
dhruba.bandopad
Junior Member
 
Join Date: Apr 2006
Posts: 7
What happens if there is no Windows Installer installed at all? Will the script crash?
dhruba.bandopad is offline   Reply With Quote
Old 19th July 2006, 13:47   #8
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
No, you'll just get no version from GetDLLVersion.

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 30th October 2007, 05:59   #9
drifa
Junior Member
 
Join Date: Oct 2007
Posts: 1
Lightbulb

go to start=>run and type msiexec
drifa is offline   Reply With Quote
Old 6th July 2008, 02:48   #10
meaningoflights
Member
 
Join Date: Jan 2008
Posts: 49
I know this thread is old but here's a working example:

!macro CHECK_MSI_VERSION

GetDllVersion "$SYSDIR\msi.dll" $R0 $R1
IntOp $R2 $R0 >> 16
IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
IntOp $R4 $R1 >> 16
IntOp $R4 $R4 & 0x0000FFFF ; $R4 now contains release
IntOp $R5 $R1 & 0x0000FFFF ; $R5 now contains build
StrCpy $0 "$R2.$R3.$R4.$R5" ; $0 now contains string like "1.2.0.192"

MessageBox MB_ICONINFORMATION|MB_OK "The version is: $R2.$R3.$R4.$R5"

!macroend

Jeremy Thompson
MCSD.Net
meaningoflights is offline   Reply With Quote
Old 3rd May 2010, 15:54   #11
jweinraub
Senior Member
 
Join Date: Jan 2004
Posts: 197
Send a message via AIM to jweinraub
How do you detect if you have an older version installed?
For example, .net framework 2.0 requires at least version 3.1 (the above installed is 3.1.4000.2435).

However I have 4.5.6001.22299 installed.

Doesn't seem to work.
code:

GetDllVersion "$SYSDIR\msi.dll" $R0 $R1
IntOp $R2 $R0 >> 16
IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
IntOp $R4 $R1 >> 16
IntOp $R4 $R4 & 0x0000FFFF ; $R4 now contains release
IntOp $R5 $R1 & 0x0000FFFF ; $R5 now contains build
StrCpy $0 "$R2.$R3.$R4.$R5" ; $0 now contains string like "1.2.0.192"

MessageBox MB_ICONINFORMATION|MB_OK "The version is: $R2.$R3.$R4.$R5"
${If} $0 < "3.1.4000.2435"
MessageBox MB_ICONINFORMATION|MB_OK "Install 3.1"
${Else}
MessageBox MB_ICONINFORMATION|MB_OK "Go away!"
${EndIf}



How can I use the individual numbers since I need it to have at least 3.1 to go on, so anything less has to have it install.
jweinraub is offline   Reply With Quote
Old 3rd May 2010, 16:07   #12
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
Originally Posted by jweinraub View Post
For example, .net framework 2.0 requires at least version 3.1 (the above installed is 3.1.4000.2435).

However I have 4.5.6001.22299 installed.

Doesn't seem to work.
code:

${If} $0 < "3.1.4000.2435"

Use ${VersionCompare} out of WordFunc.nsh (ships with NSIS) for comparing version numbers. Right now you're using a string comparison which can fail on version numbers.
( You can also replace the first part of your code with ${GetFileVersion} out of FileFunc.nsh (ships with NSIS) )

That said... even with the above deficiency, this particular case should work just fine and pop up the "Go away!" messagebox. try sticking a 'MessageBox MB_OK "[$0]"' just in front of the ${If} so you can double-check that the value of $0 is what you're expecting it to be.
( since you're reading from $SYSDIR, also keep in mind any filesystem redirection magic on 64bit platforms )
Animaether is offline   Reply With Quote
Old 3rd May 2010, 16:46   #13
jweinraub
Senior Member
 
Join Date: Jan 2004
Posts: 197
Send a message via AIM to jweinraub
Is there a different installer needed if there is a 64-bit system in place?

Because I have both .net installers for 32-bit and 64-bit versions of Windows.
My software is installed on laptops that will not have internet access therefore it is critical all prerequisites are met from the installation media itself.

What should I be aware of for 64-bit versions for the checker?

code:

${VersionCompare} $0 "3.1.4000.2435" $R0
MessageBox MB_ICONINFORMATION|MB_OK $R0 ; if R0 is 2 then install msi 3.1 installer, else go on?

jweinraub is offline   Reply With Quote
Old 3rd May 2010, 17:05   #14
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
Originally Posted by jweinraub View Post
Is there a different installer needed if there is a 64-bit system in place?
No, you can have both 32bit and 64bit installers in the same package.

Quote:
Originally Posted by jweinraub View Post
What should I be aware of for 64-bit versions for the checker?
Specifically, the Sytem32 folder.
On x64 platforms, if a 32bit application reads from the system folder (i.e. $SYSDIR), it gets redirected to a different folder named SysWOW64 (Windows(32) On Windows64). So if you need to target the 64bit version of the windows installer for that part, then you will have to disable filesystem redirection (Windows XP) or read from the SysNative folder (Vista, 7) instead.
Have a search through the forums - this pops up a few times

Quote:
Originally Posted by jweinraub View Post
code:

${VersionCompare} $0 "3.1.4000.2435" $R0
MessageBox MB_ICONINFORMATION|MB_OK $R0 ; if R0 is 2 then install msi 3.1 installer, else go on?

correct - but, again, check whether the value of $0 is what you're expecting it to be with a little messagebox first.. if you have further scripts inbetween $0 might be overwritten, or perhaps the file doesn't exist and the version returned would be 0.0.0.0, etc.
Animaether is offline   Reply With Quote
Old 3rd May 2010, 17:44   #15
jweinraub
Senior Member
 
Join Date: Jan 2004
Posts: 197
Send a message via AIM to jweinraub
Quote:
Originally Posted by Animaether View Post
No, you can have both 32bit and 64bit installers in the same package.
No I meant the WindowsInstaller-KB893803-v2-x86.exe installer. Is ther an x64 version as well.

Because I do this for x64 when it comes to .net.

code:
; Detect .net 2.0 here ;
System::Call `mscoree::GetCORVersion(w .R0, i ${NSIS_MAX_STRLEN}, *i) ?u`
StrCpy $R0 $R0 1 1

; Compare if $R0 < 2 using ${If}

${If} $R0 < 2
; First detect if this is a 64 bit OS because you will want to install that instead ...
GetVersion::WindowsPlatformArchitecture
Pop $R1
${AndIf} $R1 == 64
SetDetailsPrint textonly
DetailPrint "Installing Microsoft .NET 2.0 x64. This may take up to ten minutes, please be patient."
SetDetailsPrint none
ExecWait `"$INSTDIR\Misc\NetFx64.exe" /q:a /c:"install.exe /noaspupgrade /qb"` $R0
;SetRebootFlag true
${OrIf} $R1 == 32
SetDetailsPrint textonly
DetailPrint "Installing Microsoft .NET 2.0..."
SetDetailsPrint none
ExecWait `"$INSTDIR\Misc\dotnetfx.exe" /q:a /c:"install.exe /noaspupgrade /qb"` $R0
;SetRebootFlag true
${Else}
Goto go_on
${EndIf}



Quote:
Originally Posted by Animaether
Specifically, the Sytem32 folder.
On x64 platforms, if a 32bit application reads from the system folder (i.e. $SYSDIR), it gets redirected to a different folder named SysWOW64 (Windows(32) On Windows64). So if you need to target the 64bit version of the windows installer for that part, then you will have to disable filesystem redirection (Windows XP) or read from the SysNative folder (Vista, 7) instead.
I apologise but this part I am still unclear with. I understand the different sys dirs (like program dirs), but isnt the global variable determine the correct path at runtime?
Essentially if the user doesnt have msi installer, or an older version than 3.1 I like for it to be installed. Other wise if the version is equal to or newer than the minimum it should do nothing and go on.
jweinraub is offline   Reply With Quote
Old 3rd May 2010, 17:45   #16
jweinraub
Senior Member
 
Join Date: Jan 2004
Posts: 197
Send a message via AIM to jweinraub
why do i get all that whitespace at line breaks?!
jweinraub is offline   Reply With Quote
Old 3rd May 2010, 18:45   #17
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
There doesn't appear to be a 64-bit version of Windows Installer 3.1 - I assume 4.5 is for those platforms. The forum puts in those new lines. I did ask one of the administrators but they haven't done anything. Instead of using the GetVersion plug-in you can just !include x64.nsh and use ${If} ${RunningX64}.

Edit: If you're thinking of SetShellVarContext then that is something else. File system redirection is part of the OS and as already mentioned specifying for example C:\Windows\System32 when querying the file system from a 32-bit application, it will be redirected to C:\Windows\SysWOW64.

Edit #2: In other words MessageBox MB_OK $SYSDIR will print the expected value (System32) but if you write to it your file will be in SysWOW64 instead unless you do ${DisableX64FSRedirection} first.

Stu
Afrow UK is offline   Reply With Quote
Old 3rd May 2010, 19:03   #18
jweinraub
Senior Member
 
Join Date: Jan 2004
Posts: 197
Send a message via AIM to jweinraub
What does SetShellVarContext have to do with this? I actually make use of it only so that it installs on desktop shortcuts for All Users rather than local user (i already assume its being installed by admin).

So for intents and purposes, I can use the VersionCompare the way I am so I can just call the installer if necessary?

I assume even if it 0.0.0.0, the 3.x.x.x is still greater so it'll still install if needed, correct?

So what am I missing here by just doing it the way above?

Can I just do this?

; ... snip
${VersionCompare} $0 "3.1.4000.2435" $R0
${If} $R0 == 2
SetDetailsPrint textonly
DetailPrint "Installing Microsoft Windows Installer 3.1..."
SetDetailsPrint none
ExecWait `"$INSTDIR\Misc\WindowsInstaller-KB893803-v2-x86.exe" /quiet"` $R0
${EndIf}
; ... snip
jweinraub is offline   Reply With Quote
Old 3rd May 2010, 19:26   #19
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
SetShellVarContext has nothing to do with it, hence why I said that. VersionCompare will read an empty string as 0 (so an empty $0 will not break the code).

Stu
Afrow UK is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump