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?
Asked
Active
Viewed 2.8k times
4 Answers
18
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
- 28,010
- 19
- 106
- 164
-
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? – Jango Jun 25 '10 at 16:21
-
3I had to change the `messagebox::show` line to `MessageBox MB_YESNO "${YOUR_APP_NAME} is already installed. Uninstall the existing version?" /SD IDYES IDNO Quit`. – E-rich Oct 19 '12 at 18:57
-
It is not always true. Some software does not have a direct
under Uninstall, eg, visual C++ redistributable. In such cases, we may have to iterate over all keys under Uninstall and to check the value data of the value name "DisplayName" – Yorkwar Jun 29 '17 at 07:35
8
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
- 10,754
- 3
- 31
- 39
3
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
- 19,107
- 12
- 55
- 69
1
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
- 30,111
- 9
- 76
- 83