/*************************************************************** TrafficCam Viewer for TiVo - NSIS Installer Script This script is used to create an NSIS installer and uninstaller for the TrafficCam Viewer application for TiVo. Because this application was originally released without an installer, there's some additional code in here to try to detect that case and make sure the Service gets stopped and uninstalled properly. This will avoid leaving an orphaned service on the user's system if they forget to uninstall the old version first. Versions 1.40 and older had no installer. Note that all macros you use from FileFunc.nsh must have an !insertmacro call in the file, e.g. !insertmacro GetParent . Otherwise you'll get a compile error when trying to use GetParent. Documentation on LogicLib.nsh (${If}, ${Else}, etc.) may be found in the help files be searching for 'Variables' and selecting the first entry. Scroll up a little ways. For some reason the search in the help doesn't find it. !if is compile-time, ${If} is runtime. Lesson learned. ****************************************************************/ !include "MUI.nsh" !include "LogicLib.nsh" !include "FileFunc.nsh" !define VERSION "1.50" !define REGSUBKEY "Software\TrafficCam Viewer" !define REGKEYNAME "InstallDir" !define SERVICENAME "TrafficCam_Viewer_Service.exe" Name "TrafficCam Viewer for TiVo v${VERSION}" OutFile "trafficcam-${VERSION}-install.exe" InstallDir "$PROGRAMFILES\TrafficCam Viewer" Var RegDir Var StopServiceDir Var ServiceExecutablePath Var DelDir Var PreviousInstall ; No, Installer, or Manual Var PreviousVerDir ;Pages !insertmacro MUI_PAGE_LICENSE "trafficcam\License.txt" !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_LANGUAGE "English" !insertmacro GetParent /*************************************************************** Stop the service, presumed to have been installed via this installer. This can be called from a couple different places -- either the uninstaller, or the main section, for use when the application is being updated to a new version. This function expects $2 to be set to the install directory, obtained either via $INSTDIR or from the registry key HKCU\Software\TrafficCam Viewer. ****************************************************************/ !macro StopService ExecWait '"$StopServiceDir\${SERVICENAME}" /stop' ExecWait '"$StopServiceDir\FirewallExceptionRemove.vbs" ${SERVICENAME}' ExecWait '"$StopServiceDir\${SERVICENAME}" /uninstall' !macroend /*************************************************************** This function is used to delete everything except for the contents of the 'saves' directory. It is used when updating to a new version, or when running the complete uninstall (a complete uninstall also removes the 'saves' directory too). Expects $3 to be set to the installation directory. ****************************************************************/ !macro DeleteAllButSaves Delete $DelDir\factory-defaults\* Delete $DelDir\jars\* Delete $DelDir\logs\* Delete $DelDir\* RMDir $DelDir\factory-defaults RMDir $DelDir\jars RMDir $DelDir\logs !macroend /*************************************************************** Install everything but the 'saves' directory. This will prevent overwriting the 97205.xml and last-region-saved.xml files, which are the two that ship by default with the installation. ****************************************************************/ !macro InstallAllButSaves SetOutPath $INSTDIR File trafficcam\* SetOutPath $INSTDIR\factory-defaults File /r trafficcam\factory-defaults\* SetOutPath $INSTDIR\jars File /r trafficcam\jars\* SetOutPath $INSTDIR\logs !macroend /*************************************************************** The main execution section. ****************************************************************/ Section "TrafficCam Viewer Application (Required)" Call FindServicePathAndStopService Call RemovePreviousVersion # Note that $INSTDIR may have been modified by GetPreviousInstallInfo. ${If} $PreviousInstall == "No" SetOutPath $INSTDIR File /r trafficcam\* ${Else} !insertmacro InstallAllButSaves ${EndIf} WriteUninstaller "$INSTDIR\Uninstall.exe" CreateDirectory "$SMPROGRAMS\TrafficCam Viewer" CreateShortCut "$SMPROGRAMS\TrafficCam Viewer\Uninstall.lnk" "$INSTDIR\Uninstall.exe" ExecWait '"$INSTDIR\${SERVICENAME}" /install' ExecWait '"$INSTDIR\FirewallExceptionAdd.vbs" ${SERVICENAME}' Sleep 1500 ExecWait '"$INSTDIR\${SERVICENAME}" /start' WriteRegStr HKCU "${REGSUBKEY}" "${REGKEYNAME}" "$INSTDIR" CreateDirectory "$SMPROGRAMS\TrafficCam Viewer" CreateShortCut "$SMPROGRAMS\TrafficCam Viewer\Uninstall.lnk" "$INSTDIR\Uninstall.exe" SectionEnd /*************************************************************** Check this stuff as soon as the installer's initialized, so that it shows up before the directory page. ****************************************************************/ Function .onInit Call CheckJRE Call GetPreviousInstallInfo Call PromptUserToUpdate FunctionEnd /*************************************************************** The complete uninstaller. The uninstaller executable is assumed to be in the root of the install directory. ****************************************************************/ Section "Uninstall" StrCpy $StopServiceDir $INSTDIR !insertmacro StopService StrCpy $DelDir $INSTDIR !insertmacro DeleteAllButSaves Delete "$SMPROGRAMS\TrafficCam Viewer\Uninstall.lnk" RMDir "$SMPROGRAMS\TrafficCam Viewer" Delete $INSTDIR\saves\* RMDir $INSTDIR\saves RMDir $INSTDIR DeleteRegKey /ifempty HKCU "Software\TrafficCam Viewer" SectionEnd /*************************************************************** Check to see if the service is running, and try to determine how it was installed (either via this installer, or the "old" way, via the ZIP file and batch file. ****************************************************************/ Function FindServicePathAndStopService ${If} $PreviousInstall == "Manual" StrCpy $StopServiceDir $PreviousVerDir !insertmacro StopService ${ElseIf} $PreviousInstall == "Installer" StrCpy $StopServiceDir $PreviousVerDir !insertmacro StopService ${EndIf} FunctionEnd /*************************************************************** Check to see if the service is running, and try to determine how it was installed (either via this installer, or the "old" way, via the ZIP file and batch file. ****************************************************************/ Function GetPreviousInstallInfo ; This is the registry location the installer writes ReadRegStr $RegDir HKCU "${REGSUBKEY}" "${REGKEYNAME}" ; This will be present if the service is installed. If $RegDir is empty ; but $ServiceExecutablePath has a value, the user probably installed the old way (ZIP file) ReadRegStr $ServiceExecutablePath HKLM \ "SYSTEM\CurrentControlSet\Services\TiVo: TrafficCam Viewer" "ImagePath" ${If} $RegDir == "" ${AndIf} $ServiceExecutablePath == "" StrCpy $PreviousInstall "No" StrCpy $PreviousVerDir "" ${EndIf} ${If} $RegDir == "" ${AndIf} $ServiceExecutablePath != "" StrCpy $PreviousInstall "Manual" ${GetParent} $ServiceExecutablePath $PreviousVerDir SetOutPath $PreviousVerDir StrCpy $INSTDIR $PreviousVerDir ${EndIf} ${If} $RegDir != "" StrCpy $PreviousInstall "Installer" StrCpy $PreviousVerDir $RegDir SetOutPath $PreviousVerDir StrCpy $INSTDIR $PreviousVerDir ${EndIf} FunctionEnd /*************************************************************** If a previous version was installed (via this installer), find its directory in the registry and delete all but the save files. ****************************************************************/ Function RemovePreviousVersion ${If} $PreviousInstall == "" call GetPreviousInstallInfo ${EndIf} ${If} $PreviousInstall == "Installer" StrCpy $DelDir $PreviousVerDir !insertmacro DeleteAllButSaves ${EndIf} FunctionEnd /*************************************************************** If there was a previous installation, prompt the user to make sure it's OK to overwrite it with this version. ****************************************************************/ Function PromptUserToUpdate ${If} $PreviousInstall == "" call GetPreviousInstallInfo ${EndIf} ${If} $PreviousInstall != "No" MessageBox MB_OKCANCEL "Previous version detected in $PreviousVerDir. \ Click OK to update it or Cancel to cancel the installation." IDOK ok IDCANCEL cancel ok: goto next cancel: Abort "Installation cancelled at your request." next: ${EndIf} FunctionEnd /*************************************************************** Check for Java ****************************************************************/ Function CheckJRE ReadRegStr $0 HKLM "Software\JavaSoft\Java Runtime Environment" "CurrentVersion" ReadRegStr $1 HKLM "Software\JavaSoft\Java Development Kit" "CurrentVersion" ${If} $0 == "" ${AndIf} $1 == "" MessageBox MB_OKCANCEL "I couldn't find a Java runtime on your system.\ You should install Java FIRST before installing this application. You can \ install Java from http://java.com/java/download. Click \ 'OK' to install anyway, or 'Cancel' to cancel this installation." IDOK ok IDCANCEL cancel ok: goto next cancel: # ExecShell "open" "http://java.com/java/download" # BringToFront Abort "Installation cancelled at your request." next: ${EndIf} FunctionEnd