views:

3215

answers:

4

I'm using NSIS to create an installer for a program, what is the best way to detect if this program is already installed? Also, since I'm running the installer from the autorun.inf, can I immediately quit the installer if it locates an installed copy? Is there a better way to do this?

A: 

This is generally done by having NSIS insert a registry key for your product when it installs. It is then an easy manner to detect if that registry key is present and if so, bail

Kevin
Any example or pointer you can give on doing that?
Abdullah Jibaly
+3  A: 

How about this. I had this in an old NSIS script laying around.

; Check to see if already installed
  ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\<YOUR-APP-NAME>" "UninstallString"
  IfFileExists $R0 +1 NotInstalled
  messagebox::show MB_DEFBUTTON4|MB_TOPMOST "<YOUR-APP-NAME>" \
    "0,103" \
    "<YOUR-APP-NAME> is already installed." \
    "Launch Uninstall" "Cancel"
    Pop $R1
  StrCmp $R1 2 Quit +1
  Exec $R0
Quit:
  Quit

NotInstalled:
Magnus Johansson
@Magnus. You mentioned Launch Uninstall. I could not really invoke Uninstall in my .nsi script by using this above code. Can you tell me how can i call Uninstall if my program is already installed?
Novice
+1  A: 

I've been using a slightly more sophisticated test which also checks the version of the installed software:

!define PRODUCT_VERSION "1.2.0"

!include "WordFunc.nsh"
  !insertmacro VersionCompare

Var UNINSTALL_OLD_VERSION

...

Section "Core System" CoreSystem
  StrCmp $UNINSTALL_OLD_VERSION "" core.files
  ExecWait '$UNINSTALL_OLD_VERSION'

core.files:

  ...
  WriteRegStr HKLM "Software\${PRODUCT_REG_KEY}" "" $INSTDIR
  WriteRegStr HKLM "Software\${PRODUCT_REG_KEY}" "Version" "${PRODUCT_VERSION}"
  ...
SectionEnd

...

Function .onInit
  ;Check earlier installation
  ClearErrors
  ReadRegStr $0 HKLM "Software\${PRODUCT_REG_KEY}" "Version"
  IfErrors init.uninst ; older versions might not have "Version" string set
  ${VersionCompare} $0 ${PRODUCT_VERSION} $1
  IntCmp $1 2 init.uninst
    MessageBox MB_YESNO|MB_ICONQUESTION "${PRODUCT_NAME} version $0 seems to be already installed on your system.$\nWould you like to proceed with the installation of version ${PRODUCT_VERSION}?" \
        IDYES init.uninst
    Quit

init.uninst:
  ClearErrors
  ReadRegStr $0 HKLM "Software\${PRODUCT_REG_KEY}" ""
  IfErrors init.done
  StrCpy $UNINSTALL_OLD_VERSION '"$0\uninstall.exe" /S _?=$0'

init.done:
FunctionEnd

You of course have to fill in the details, this only gives you a rough skeleton.

David Hanak
A: 

After creating your uninstaller create a product name entry in registry

!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANY_NAME} ${PRODUCT_NAME}"
Section -Post
  SetShellVarContext current
  WriteUninstaller "${UNINST_PATH}\uninst.exe"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"

To see if the product is installed do

Function IsProductInstalled
  ClearErrors
  ReadRegStr $2 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName"  
  StrCmp $2 "" exit

In your uninstall you should be doing

Section Uninstall
    DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
Cherian