blob: e5ba59264962622f3f7ceae6c758be553ea8b61a [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
# Constants and variables
#
!define Application "ApacheDS"
!define Version "${version}"
!define InstallerIcon "installer.ico"
!define UninstallerIcon "uninstaller.ico"
!define WelcomeImage "welcome.bmp"
!define HeaderImage "header.bmp"
!define OutFile "${finalname}"
!define InstallationFiles "${installationFiles}"
!define InstancesFiles "${instancesFiles}"
!define JREVersion "1.5.0"
!define INSTDIR_REG_ROOT "HKLM"
!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${Application}"
# Variables needed for JRE detection
Var JREPath
#
# Modules inclusions
#
# Modern UI module
!include "MUI.nsh"
# Sections module
!include "Sections.nsh"
#
# Macros (which need to be defined before they're used)
#
# Creates an Internet shortcut
!macro CreateInternetShortcut FILENAME URL ;ICONFILE ICONINDEX
WriteINIStr "${FILENAME}.url" "InternetShortcut" "URL" "${URL}"
!macroend
#
# Configuration
#
# Name of the application
Name "${Application}"
# Output installer file
OutFile "../${OutFile}"
# Default install directory
InstallDir "$PROGRAMFILES\${Application}"
# Branding text
BrandingText "${Application} - ${Version}"
# Activating XPStyle
XPStyle on
# Installer icon
!define MUI_ICON "${InstallerIcon}"
# Uninstaller icon
!define MUI_UNICON "${UninstallerIcon}"
# Welcome image
!define MUI_WELCOMEFINISHPAGE_BITMAP "${WelcomeImage}"
# Activating header image
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${HeaderImage}"
# Activating small description for the components page
!define MUI_COMPONENTSPAGE_SMALLDESC
# Activating a confirmation when aborting the installation
!define MUI_ABORTWARNING
#
# Pages
#
#
# Installer pages
#
# Welcome page
!insertmacro MUI_PAGE_WELCOME
# License page
!insertmacro MUI_PAGE_LICENSE "${InstallationFiles}\LICENSE"
# Installation directory page
Var SERVER_HOME_DIR
!define MUI_DIRECTORYPAGE_VARIABLE $SERVER_HOME_DIR
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Server Home Directory"
!define MUI_DIRECTORYPAGE_TEXT_TOP "Select the directory where you would like to install ${Application}"
!insertmacro MUI_PAGE_DIRECTORY
# Instances directory page
Var INSTANCES_HOME_DIR
!define MUI_PAGE_CUSTOMFUNCTION_PRE PreInstancesDir
!define MUI_DIRECTORYPAGE_VARIABLE $INSTANCES_HOME_DIR
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Server Instances Home Directory"
!define MUI_DIRECTORYPAGE_TEXT_TOP "Select the directory where you would like instances data to be stored.$\n$\nThis directory will be the home location for new instances."
!insertmacro MUI_PAGE_DIRECTORY
# JRE directory page
Var JAVA_HOME_DIR
!define MUI_DIRECTORYPAGE_VARIABLE $JAVA_HOME_DIR
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Java Home Directory"
!define MUI_DIRECTORYPAGE_TEXT_TOP "Select the Java home directory that you would like to use for running the installed applications."
!insertmacro MUI_PAGE_DIRECTORY
# Installation page
!insertmacro MUI_PAGE_INSTFILES
# Finish page
!insertmacro MUI_PAGE_FINISH
#
# Uninstaller pages
#
# Confirmation page
!insertmacro MUI_UNPAGE_CONFIRM
# Uninstallation page
!insertmacro MUI_UNPAGE_INSTFILES
#
# Languages (the first one is the default one)
#
!insertmacro MUI_LANGUAGE "English"
#
# Sections
#
# Installer section
Section
# Writing installation files
SetOutPath "$SERVER_HOME_DIR"
# Adding installation source files
File /r "${InstallationFiles}\*"
# Converting files line encoding
Push "$SERVER_HOME_DIR"
Push "*.txt"
Call ConvertFiles
# Converting files line encoding
Push "$SERVER_HOME_DIR\conf"
Push "*.*"
Call ConvertFiles
# Replacing java home directory in config file
GetFunctionAddress $R0 ReplaceJavaHome # handle to callback fn
Push $R0
Push "$SERVER_HOME_DIR\conf\wrapper.conf" # file to replace in
Call ReplaceInFile
# Configuring registries for the uninstaller
WriteRegStr "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "SERVER_HOME_DIR" $SERVER_HOME_DIR
WriteRegStr "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "INSTANCES_HOME_DIR" $INSTANCES_HOME_DIR
WriteRegStr "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "DisplayName" "${Application} - (remove only)"
WriteRegStr "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "DisplayIcon" "$SERVER_HOME_DIR\uninstall.exe"
WriteRegStr "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "UninstallString" '"$SERVER_HOME_DIR\uninstall.exe"'
WriteRegDWORD "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "NoModify" "1"
WriteRegDWORD "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "NoRepair" "1"
# Creating the uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
# Creating directory in start menu
CreateDirectory "$SMPROGRAMS\${Application}"
# Creating links in start menu
!insertmacro CreateInternetShortcut "$SMPROGRAMS\${Application}\Basic Users Guide" "http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html"
!insertmacro CreateInternetShortcut "$SMPROGRAMS\${Application}\Advanced Users Guide" "http://directory.apache.org/apacheds/1.5/apacheds-v15-advanced-users-guide.html"
!insertmacro CreateInternetShortcut "$SMPROGRAMS\${Application}\Developers Guide" "http://directory.apache.org/apacheds/1.5/apacheds-v15-developers-guide.html"
# Creating a shortcut to the 'Manage ApacheDS' utility
CreateShortCut "$SMPROGRAMS\${Application}\Manage ApacheDS.lnk" "$SERVER_HOME_DIR\Manage ApacheDS.exe" "" "$SERVER_HOME_DIR\Manage ApacheDS.exe" 0
# Creating a shortcut to the uninstaller
CreateShortCut "$SMPROGRAMS\${Application}\Uninstall ApacheDS.lnk" "$SERVER_HOME_DIR\Uninstall.exe" "" "$SERVER_HOME_DIR\Uninstall.exe" 0
# Writing instances files
SetOutPath "$INSTANCES_HOME_DIR"
# Adding instances source files
File /r "${InstancesFiles}\*"
# Converting files line encoding
Push "$INSTANCES_HOME_DIR\conf"
Push "*.*"
Call ConvertFiles
# Replacing installation directory in config file
GetFunctionAddress $R0 ReplaceInstallationDirectory # handle to callback fn
Push $R0
Push "$INSTANCES_HOME_DIR\default\conf\wrapper.conf" # file to replace in
Call ReplaceInFile
# Registering the server instance
Call RegisterInstance
SectionEnd
# Uninstaller section
Section Uninstall
# Getting install locations
ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "SERVER_HOME_DIR"
StrCpy $SERVER_HOME_DIR $R1
ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "INSTANCES_HOME_DIR"
StrCpy $INSTANCES_HOME_DIR $R1
#Need to parse a list of instances or directories somehow
Call un.RegisterInstance
# Remove shortcuts and folders in the start menu
RMDir /r "$SMPROGRAMS\${Application}"
# Removing registry keys
DeleteRegKey "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}"
DeleteRegKey "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}"
# Removing files in root, then all dirs created by the installer (leave user added or instance dirs)
Delete "$INSTDIR\*"
RMDir /r "$INSTDIR\bin"
RMDir /r "$INSTDIR\conf"
RMDir /r "$INSTDIR\lib"
SectionEnd
#
# Functions
#
#
# <ConvertFiles>
#
# Converts Unix to CR/LF for Windows
Function ConvertFiles
Pop $R0
Pop $R1
FindFirst $R2 $R3 "$R1\$R0"
loop:
StrCmp $R3 "" done
Push "$R1\$R3"
Call ConvertUnixNewLines
FindNext $R2 $R3
Goto loop
done:
FindClose $R2
Pop $R3
Pop $R2
Pop $R1
Pop $R0
FunctionEnd
#
# </ConvertFiles>
#
#
# <RegisterInstance>
#
Function RegisterInstance
nsExec::ExecToLog '"$SERVER_HOME_DIR\bin\wrapper.exe" -i "$INSTANCES_HOME_DIR\default\conf\wrapper.conf" set.INSTANCE_DIRECTORY="$INSTANCES_HOME_DIR\default" set.INSTANCE="default"'
FunctionEnd
#
# </RegisterInstance>
#
#
# <un.RegisterInstance>
#
Function un.RegisterInstance
nsExec::ExecToLog '"$SERVER_HOME_DIR\bin\wrapper.exe" -r "$INSTANCES_HOME_DIR\default\conf\wrapper.conf" set.INSTANCE_DIRECTORY="$INSTANCES_HOME_DIR\default" set.INSTANCE="default"'
FunctionEnd
#
# </un.RegisterInstance>
#
#
# <.onInstSuccess>
#
Function .onInstSuccess
# Start the server
MessageBox MB_YESNO|MB_ICONQUESTION "Do you want to start the default server instance?" IDYES startService IDNO End
startService:
nsExec::ExecToLog '"$SERVER_HOME_DIR\bin\wrapper.exe" -t "$INSTANCES_HOME_DIR\default\conf\wrapper.conf" set.INSTANCE_DIRECTORY="$INSTANCES_HOME_DIR\default" set.INSTANCE="default"'
End:
FunctionEnd
#
# </.onInstSuccess>
#
#
# <.onInit>
#
Function .onInit
SetCurInstType 0
SetAutoClose false
StrCpy $SERVER_HOME_DIR "$PROGRAMFILES\ApacheDS"
Call CheckInstalledJRE
StrCpy $JAVA_HOME_DIR "$JREPath"
FunctionEnd
#
# </.onInit>
#
#
# <PreInstancesDir>
#
Function PreInstancesDir
StrCpy $INSTANCES_HOME_DIR $SERVER_HOME_DIR\instances
FunctionEnd
#
# </PreInstancesDir>
#
#
# <CheckInstalledJRE>
#
Function CheckInstalledJRE
Push "${JREVersion}"
Call DetectJRE
Exch $0 ; Get return value from stack
StrCmp $0 "0" End
StrCmp $0 "-1" End
Goto JREAlreadyInstalled
JREAlreadyInstalled:
StrCpy $JREPath "$0"
Pop $0 # Restore $0
Return
End:
FunctionEnd
#
# </CheckInstalledJRE>
#
#
# <DetectJRE>
#
# DetectJRE. Version requested is on the stack.
# Returns (on stack): 0 - JRE not found. -1 - JRE found but too old. Otherwise - Path to JAVA EXE
# Stack value will be overwritten!
Function DetectJRE
Exch $0 ; Get version requested
; Now the previous value of $0 is on the stack, and the asked for version of JDK is in $0
Push $1 ; $1 = Java version string (ie 1.5.0)
Push $2 ; $2 = Javahome
Push $3 ; $3 and $4 are used for checking the major/minor version of java
Push $4
;MessageBox MB_OK "Detecting JRE"
ReadRegStr $1 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" "CurrentVersion"
;MessageBox MB_OK "Read : $1"
StrCmp $1 "" DetectTry2
ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment\$1" "JavaHome"
;MessageBox MB_OK "Read 3: $2"
StrCmp $2 "" DetectTry2
Goto GetJRE
DetectTry2:
ReadRegStr $1 HKLM "SOFTWARE\JavaSoft\Java Development Kit" "CurrentVersion"
;MessageBox MB_OK "Detect Read : $1"
StrCmp $1 "" NoFound
ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Development Kit\$1" "JavaHome"
;MessageBox MB_OK "Detect Read 3: $2"
StrCmp $2 "" NoFound
GetJRE:
; $0 = version requested. $1 = version found. $2 = javaHome
;MessageBox MB_OK "Getting JRE"
IfFileExists "$2\bin\java.exe" 0 NoFound
StrCpy $3 $0 1 ; Get major version. Example: $1 = 1.5.0, now $3 = 1
StrCpy $4 $1 1 ; $3 = major version requested, $4 = major version found
;MessageBox MB_OK "Want $3 , found $4"
IntCmp $4 $3 0 FoundOld FoundNew
StrCpy $3 $0 1 2
StrCpy $4 $1 1 2 ; Same as above. $3 is minor version requested, $4 is minor version installed
;MessageBox MB_OK "Want $3 , found $4"
IntCmp $4 $3 FoundNew FoundOld FoundNew
NoFound:
;MessageBox MB_OK "JRE not found"
Push "0"
Goto DetectJREEnd
FoundOld:
MessageBox MB_OK "JRE too old: $3 is older than $4"
; Push ${TEMP2}
Push "-1"
Goto DetectJREEnd
FoundNew:
;MessageBox MB_OK "JRE is new: $3 is newer than $4"
Push "$2"
; Push "OK"
; Return
Goto DetectJREEnd
DetectJREEnd:
; Top of stack is return value, then r4,r3,r2,r1
Exch ; => r4,rv,r3,r2,r1,r0
Pop $4 ; => rv,r3,r2,r1r,r0
Exch ; => r3,rv,r2,r1,r0
Pop $3 ; => rv,r2,r1,r0
Exch ; => r2,rv,r1,r0
Pop $2 ; => rv,r1,r0
Exch ; => r1,rv,r0
Pop $1 ; => rv,r0
Exch ; => r0,rv
Pop $0 ; => rv
FunctionEnd
#
# </DetectJRE>
#
#
# <ConvertUnixNewLines>
#
Function ConvertUnixNewLines
; Usage:
;Push "path\to\text_file.txt"
;Call ConvertUnixNewLines
Exch $R0 ;file #1 path
Push $R1 ;file #1 handle
Push $R2 ;file #2 path
Push $R3 ;file #2 handle
Push $R4 ;data
Push $R5
FileOpen $R1 $R0 r
GetTempFileName $R2
FileOpen $R3 $R2 w
loopRead:
ClearErrors
FileRead $R1 $R4
IfErrors doneRead
StrCpy $R5 $R4 1 -1
StrCmp $R5 $\n 0 +4
StrCpy $R5 $R4 1 -2
StrCmp $R5 $\r +3
StrCpy $R4 $R4 -1
StrCpy $R4 "$R4$\r$\n"
FileWrite $R3 $R4
Goto loopRead
doneRead:
FileClose $R3
FileClose $R1
SetDetailsPrint none
Delete $R0
Rename $R2 $R0
SetDetailsPrint both
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
FunctionEnd
#
# </ConvertUnixNewLines>
#
#
# <ReplaceInFile>
#
Function ReplaceInFile
;
Exch $R0 ;file name to search in
Exch
Exch $R4 ;callback function handle
Push $R1 ;file handle
Push $R2 ;temp file name
Push $R3 ;temp file handle
Push $R5 ;line read
GetTempFileName $R2
FileOpen $R1 $R0 r ;file to search in
FileOpen $R3 $R2 w ;temp file
loop_read:
ClearErrors
FileRead $R1 $R5 ;read line
Push $R5 ; put line on stack
Call $R4
Pop $R5 ; read line from stack
IfErrors exit
FileWrite $R3 $R5 ;write modified line
Goto loop_read
exit:
FileClose $R1
FileClose $R3
SetDetailsPrint none
Delete $R0
Rename $R2 $R0
Delete $R2
SetDetailsPrint both
; pop in reverse order
Pop $R5
Pop $R3
Pop $R2
Pop $R1
Pop $R4
Pop $R0
FunctionEnd
#
# </ReplaceInFile>
#
#
# <ReplaceJavaHome>
#
# Replaces the '@java.home@' placeholder
Function ReplaceJavaHome
Push $R1
Exch
Push "@java.home@" # String to find
Push "$JAVA_HOME_DIR" # Replacement string
Call StrReplace
; restore stack
Exch
Pop $R1
FunctionEnd
#
# </ReplaceJavaHome>
#
#
# <ReplaceInstallationDirectory>
#
# Replaces the '@installation.directory@' placeholder
Function ReplaceInstallationDirectory
Push $R1
Exch
Push "@installation.directory@" # String to find
Push "$SERVER_HOME_DIR" # Replacement string
Call StrReplace
; restore stack
Exch
Pop $R1
FunctionEnd
#
# </ReplaceInstallationDirectory>
#
#
# <StrReplace>
#
Var STR_REPLACE_VAR_0
Var STR_REPLACE_VAR_1
Var STR_REPLACE_VAR_2
Var STR_REPLACE_VAR_3
Var STR_REPLACE_VAR_4
Var STR_REPLACE_VAR_5
Var STR_REPLACE_VAR_6
Var STR_REPLACE_VAR_7
Var STR_REPLACE_VAR_8
Function StrReplace
Exch $STR_REPLACE_VAR_2
Exch 1
Exch $STR_REPLACE_VAR_1
Exch 2
Exch $STR_REPLACE_VAR_0
StrCpy $STR_REPLACE_VAR_3 -1
StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
loop:
IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
Goto loop
found:
StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
Goto loop
done:
Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
Exch $STR_REPLACE_VAR_0
FunctionEnd
!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
Push "${HAYSTACK}"
Push "${NEEDLE}"
Push "${NEEDLE2}"
Call StrReplace
Pop "${OUT}"
!macroend
!define StrReplace '!insertmacro "_strReplaceConstructor"'
#
# </StrReplace>
#