You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pa...@apache.org on 2012/02/16 15:55:38 UTC

svn commit: r1245007 - in /directory/studio/trunk/application: application-win32-x86-exe/ application-win32-x86-exe/src/main/resources/ application-win32-x86_64-exe/ application-win32-x86_64-exe/src/main/resources/

Author: pamarcelot
Date: Thu Feb 16 14:55:37 2012
New Revision: 1245007

URL: http://svn.apache.org/viewvc?rev=1245007&view=rev
Log:
Fix for DIRSTUDIO-782 (Improve Windows installer with JRE detection and creation of 'Apache Directory Studio.ini' file).

Added:
    directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/Apache Directory Studio.ini
    directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/Apache Directory Studio.ini
Modified:
    directory/studio/trunk/application/application-win32-x86-exe/pom.xml
    directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/installer.nsi
    directory/studio/trunk/application/application-win32-x86_64-exe/pom.xml
    directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/installer.nsi

Modified: directory/studio/trunk/application/application-win32-x86-exe/pom.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86-exe/pom.xml?rev=1245007&r1=1245006&r2=1245007&view=diff
==============================================================================
--- directory/studio/trunk/application/application-win32-x86-exe/pom.xml (original)
+++ directory/studio/trunk/application/application-win32-x86-exe/pom.xml Thu Feb 16 14:55:37 2012
@@ -84,6 +84,7 @@
                 <copy file="src/main/resources/header_studio.bmp" todir="${tmp-dir}"/>
                 <copy file="src/main/resources/studio-installer.ico" todir="${tmp-dir}"/>
                 <copy file="src/main/resources/welcome_studio.bmp" todir="${tmp-dir}"/>
+                <copy file="src/main/resources/Apache Directory Studio.ini" todir="${tmp-dir}"/>
               </target>
             </configuration>
             <goals>

Added: directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/Apache Directory Studio.ini
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/Apache%20Directory%20Studio.ini?rev=1245007&view=auto
==============================================================================
--- directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/Apache Directory Studio.ini (added)
+++ directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/Apache Directory Studio.ini Thu Feb 16 14:55:37 2012
@@ -0,0 +1,2 @@
+-vm
+@java.home@\bin
\ No newline at end of file

Modified: directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/installer.nsi
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/installer.nsi?rev=1245007&r1=1245006&r2=1245007&view=diff
==============================================================================
--- directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/installer.nsi (original)
+++ directory/studio/trunk/application/application-win32-x86-exe/src/main/resources/installer.nsi Thu Feb 16 14:55:37 2012
@@ -27,9 +27,13 @@
     !define HeaderImage "header_studio.bmp"
     !define OutFile "../@installer-file-name@"
     !define SourceFolder "ApacheDirectoryStudio-win32-x86-${Version}"
+    !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
 #
@@ -98,6 +102,13 @@
     # Directory page
     #!define MUI_DIRECTORYPAGE_VARIABLE $APPLICATION_HOME_DIR
     !insertmacro MUI_PAGE_DIRECTORY
+
+    # JRE directory page
+    Var JAVA_HOME_DIR
+    !define MUI_DIRECTORYPAGE_VARIABLE $JAVA_HOME_DIR
+    !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "$(javaPageTitle)"
+    !define MUI_DIRECTORYPAGE_TEXT_TOP "$(javaPageMessage)"
+    !insertmacro MUI_PAGE_DIRECTORY
     
     # Installation page
     !insertmacro MUI_PAGE_INSTFILES
@@ -116,61 +127,6 @@
     !insertmacro MUI_UNPAGE_INSTFILES
 
 #
-# Languages (the first one is the default one)
-#
-    !insertmacro MUI_LANGUAGE "English"
-    !insertmacro MUI_LANGUAGE "French"
-    !insertmacro MUI_LANGUAGE "German"
-    
-#
-# Functions
-#
-    # Internationalized strings
-    LangString message ${LANG_ENGLISH} "${Application} is already installed.$\n$\nClick 'OK' to remove the previous version$\nor 'Cancel' to cancel this installation."
-    LangString message ${LANG_FRENCH} "${Application} est déjà installé.$\n$\nCliquez sur 'OK' pour supprimer la version précédente$\nou sur 'Annuler' pour annuler cette installation."
-    LangString message ${LANG_GERMAN} "${Application} ist bereits installiert.$\n$\nKlicke 'OK' um die frühere Version zu entfernen$\noder 'Abbruch' um die Installation abzubrechen."
-
-    # onInit function
-    Function .onInit
-        # Preventing the window to close automatically at the end of the (un)installation
-        SetAutoClose false
-    
-        # Verifying if the application is already installed
-        ReadRegStr $R0 "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "UninstallString"
-        StrCmp $R0 "" done
-        
-        # Getting install location
-        ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir"
-        StrCmp $R1 "" done
-    
-        # The application is already installed
-        # Asking before running the uninstaller
-        MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(message)" \
-        IDOK uninst
-        Abort
-      
-        # Running the uninstaller
-        uninst:
-            ExecWait '$R0 _?=$R1'
-            
-        done:
-            # Preparing the uninstall log
-            !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
-    FunctionEnd
-
-    # onInstSuccess function
-    Function .onInstSuccess
-         # Updating the uninstall log
-         !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
-    FunctionEnd
-    
-    # UN.onInit function
-    Function UN.onInit 
-         # Begin uninstall
-         !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
-    FunctionEnd
-
-#
 # Sections
 #
     # Installer section
@@ -182,6 +138,13 @@
         
         # Adding installer source files
         File /r "${SourceFolder}\*"
+        File "Apache Directory Studio.ini"
+        
+        # Replacing Java home directory in config file
+        GetFunctionAddress $R0 ReplaceJavaHome # handle to callback fn
+        Push $R0
+        Push "$INSTDIR\Apache Directory Studio.ini" # file to replace in
+        Call ReplaceInFile
         
         # Storing install location
         WriteRegStr "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir" $INSTDIR
@@ -230,3 +193,322 @@
         # Removing registry keys
         DeleteRegKey "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}"
     SectionEnd
+
+#
+# Languages (the first one is the default one)
+#
+    !insertmacro MUI_LANGUAGE "English"
+    !insertmacro MUI_LANGUAGE "French"
+    !insertmacro MUI_LANGUAGE "German"
+    
+#
+# Functions
+#
+    # Internationalized strings
+    LangString alreadyInstalledMessage ${LANG_ENGLISH} "${Application} is already installed.$\n$\nClick 'OK' to remove the previous version$\nor 'Cancel' to cancel this installation."
+    LangString alreadyInstalledMessage ${LANG_FRENCH} "${Application} est déjà installé.$\n$\nCliquez sur 'OK' pour supprimer la version précédente$\nou sur 'Annuler' pour annuler cette installation."
+    LangString alreadyInstalledMessage ${LANG_GERMAN} "${Application} ist bereits installiert.$\n$\nKlicke 'OK' um die frühere Version zu entfernen$\noder 'Abbruch' um die Installation abzubrechen."
+
+    LangString javaPageTitle ${LANG_ENGLISH} "Java Home Directory"
+    LangString javaPageTitle ${LANG_FRENCH} "Répertoire Java Home"
+    LangString javaPageTitle ${LANG_GERMAN} "Java Home Verzeichnis"
+    
+    LangString javaPageMessage ${LANG_ENGLISH} "Select the Java Home directory you would like to use to run ${Application}."
+    LangString javaPageMessage ${LANG_FRENCH} "Sélectionnez le répertoire Java Home que vous souhaitez utiliser pour ${Application}"
+    LangString javaPageMessage ${LANG_GERMAN} "Wählen Sie das Java Home Verzeichnis, das Sie verwenden möchten, um ${Application} laufen."
+    
+    #
+    # <onInit>
+    #
+    
+    Function .onInit
+        # Preventing the window to close automatically at the end of the (un)installation
+        SetAutoClose false
+    
+        # Verifying if the application is already installed
+        ReadRegStr $R0 "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "UninstallString"
+        StrCmp $R0 "" done
+        
+        # Getting install location
+        ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir"
+        StrCmp $R1 "" done
+    
+        # The application is already installed
+        # Asking before running the uninstaller
+        MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(alreadyInstalledMessage)" \
+        IDOK uninst
+        Abort
+      
+        # Running the uninstaller
+        uninst:
+            ExecWait '$R0 _?=$R1'
+            
+        done:
+            # Checking installed JRE
+            Call CheckInstalledJRE
+            StrCpy $JAVA_HOME_DIR "$JREPath"
+        
+            # Preparing the uninstall log
+            !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
+    FunctionEnd
+
+    #
+    # </onInit>
+    #
+    
+    #
+    # <onInstSuccess>
+    #
+    
+    Function .onInstSuccess
+         # Updating the uninstall log
+         !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
+    FunctionEnd
+    
+    #
+    # </onInstSuccess>
+    #
+    
+    #
+    # <UN.onInit>
+    #
+    
+    Function UN.onInit 
+         # Begin uninstall
+         !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
+    FunctionEnd
+    
+    #
+    # </UN.onInit>
+    #
+        
+    #
+    # <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>
+    #
+
+    #
+    # <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>
+    #
+    
+    #
+    # <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>
+    #

Modified: directory/studio/trunk/application/application-win32-x86_64-exe/pom.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86_64-exe/pom.xml?rev=1245007&r1=1245006&r2=1245007&view=diff
==============================================================================
--- directory/studio/trunk/application/application-win32-x86_64-exe/pom.xml (original)
+++ directory/studio/trunk/application/application-win32-x86_64-exe/pom.xml Thu Feb 16 14:55:37 2012
@@ -84,6 +84,7 @@
                 <copy file="src/main/resources/header_studio.bmp" todir="${tmp-dir}"/>
                 <copy file="src/main/resources/studio-installer.ico" todir="${tmp-dir}"/>
                 <copy file="src/main/resources/welcome_studio.bmp" todir="${tmp-dir}"/>
+                <copy file="src/main/resources/Apache Directory Studio.ini" todir="${tmp-dir}"/>
               </target>
             </configuration>
             <goals>

Added: directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/Apache Directory Studio.ini
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/Apache%20Directory%20Studio.ini?rev=1245007&view=auto
==============================================================================
--- directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/Apache Directory Studio.ini (added)
+++ directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/Apache Directory Studio.ini Thu Feb 16 14:55:37 2012
@@ -0,0 +1,2 @@
+-vm
+@java.home@\bin
\ No newline at end of file

Modified: directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/installer.nsi
URL: http://svn.apache.org/viewvc/directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/installer.nsi?rev=1245007&r1=1245006&r2=1245007&view=diff
==============================================================================
--- directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/installer.nsi (original)
+++ directory/studio/trunk/application/application-win32-x86_64-exe/src/main/resources/installer.nsi Thu Feb 16 14:55:37 2012
@@ -27,9 +27,13 @@
     !define HeaderImage "header_studio.bmp"
     !define OutFile "../@installer-file-name@"
     !define SourceFolder "ApacheDirectoryStudio-win32-x86_64-${Version}"
+    !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
 #
@@ -98,6 +102,13 @@
     # Directory page
     #!define MUI_DIRECTORYPAGE_VARIABLE $APPLICATION_HOME_DIR
     !insertmacro MUI_PAGE_DIRECTORY
+
+    # JRE directory page
+    Var JAVA_HOME_DIR
+    !define MUI_DIRECTORYPAGE_VARIABLE $JAVA_HOME_DIR
+    !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "$(javaPageTitle)"
+    !define MUI_DIRECTORYPAGE_TEXT_TOP "$(javaPageMessage)"
+    !insertmacro MUI_PAGE_DIRECTORY
     
     # Installation page
     !insertmacro MUI_PAGE_INSTFILES
@@ -116,61 +127,6 @@
     !insertmacro MUI_UNPAGE_INSTFILES
 
 #
-# Languages (the first one is the default one)
-#
-    !insertmacro MUI_LANGUAGE "English"
-    !insertmacro MUI_LANGUAGE "French"
-    !insertmacro MUI_LANGUAGE "German"
-    
-#
-# Functions
-#
-    # Internationalized strings
-    LangString message ${LANG_ENGLISH} "${Application} is already installed.$\n$\nClick 'OK' to remove the previous version$\nor 'Cancel' to cancel this installation."
-    LangString message ${LANG_FRENCH} "${Application} est déjà installé.$\n$\nCliquez sur 'OK' pour supprimer la version précédente$\nou sur 'Annuler' pour annuler cette installation."
-    LangString message ${LANG_GERMAN} "${Application} ist bereits installiert.$\n$\nKlicke 'OK' um die frühere Version zu entfernen$\noder 'Abbruch' um die Installation abzubrechen."
-
-    # onInit function
-    Function .onInit
-        # Preventing the window to close automatically at the end of the (un)installation
-        SetAutoClose false
-    
-        # Verifying if the application is already installed
-        ReadRegStr $R0 "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "UninstallString"
-        StrCmp $R0 "" done
-        
-        # Getting install location
-        ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir"
-        StrCmp $R1 "" done
-    
-        # The application is already installed
-        # Asking before running the uninstaller
-        MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(message)" \
-        IDOK uninst
-        Abort
-      
-        # Running the uninstaller
-        uninst:
-            ExecWait '$R0 _?=$R1'
-            
-        done:
-            # Preparing the uninstall log
-            !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
-    FunctionEnd
-
-    # onInstSuccess function
-    Function .onInstSuccess
-         # Updating the uninstall log
-         !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
-    FunctionEnd
-    
-    # UN.onInit function
-    Function UN.onInit 
-         # Begin uninstall
-         !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
-    FunctionEnd
-
-#
 # Sections
 #
     # Installer section
@@ -182,6 +138,13 @@
         
         # Adding installer source files
         File /r "${SourceFolder}\*"
+        File "Apache Directory Studio.ini"
+        
+        # Replacing Java home directory in config file
+        GetFunctionAddress $R0 ReplaceJavaHome # handle to callback fn
+        Push $R0
+        Push "$INSTDIR\Apache Directory Studio.ini" # file to replace in
+        Call ReplaceInFile
         
         # Storing install location
         WriteRegStr "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir" $INSTDIR
@@ -230,3 +193,322 @@
         # Removing registry keys
         DeleteRegKey "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}"
     SectionEnd
+
+#
+# Languages (the first one is the default one)
+#
+    !insertmacro MUI_LANGUAGE "English"
+    !insertmacro MUI_LANGUAGE "French"
+    !insertmacro MUI_LANGUAGE "German"
+    
+#
+# Functions
+#
+    # Internationalized strings
+    LangString message ${LANG_ENGLISH} "${Application} is already installed.$\n$\nClick 'OK' to remove the previous version$\nor 'Cancel' to cancel this installation."
+    LangString message ${LANG_FRENCH} "${Application} est déjà installé.$\n$\nCliquez sur 'OK' pour supprimer la version précédente$\nou sur 'Annuler' pour annuler cette installation."
+    LangString message ${LANG_GERMAN} "${Application} ist bereits installiert.$\n$\nKlicke 'OK' um die frühere Version zu entfernen$\noder 'Abbruch' um die Installation abzubrechen."
+
+    LangString javaPageTitle ${LANG_ENGLISH} "Java Home Directory"
+    LangString javaPageTitle ${LANG_FRENCH} "Répertoire Java Home"
+    LangString javaPageTitle ${LANG_GERMAN} "Java Home Verzeichnis"
+    
+    LangString javaPageMessage ${LANG_ENGLISH} "Select the Java Home directory you would like to use to run ${Application}."
+    LangString javaPageMessage ${LANG_FRENCH} "Sélectionnez le répertoire Java Home que vous souhaitez utiliser pour ${Application}"
+    LangString javaPageMessage ${LANG_GERMAN} "Wählen Sie das Java Home Verzeichnis, das Sie verwenden möchten, um ${Application} laufen."
+    
+    #
+    # <onInit>
+    #
+    
+    Function .onInit
+        # Preventing the window to close automatically at the end of the (un)installation
+        SetAutoClose false
+    
+        # Verifying if the application is already installed
+        ReadRegStr $R0 "${INSTDIR_REG_ROOT}" "${INSTDIR_REG_KEY}" "UninstallString"
+        StrCmp $R0 "" done
+        
+        # Getting install location
+        ReadRegStr $R1 "${INSTDIR_REG_ROOT}" "SOFTWARE\${Application}" "InstallDir"
+        StrCmp $R1 "" done
+    
+        # The application is already installed
+        # Asking before running the uninstaller
+        MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(alreadyInstalledMessage)" \
+        IDOK uninst
+        Abort
+      
+        # Running the uninstaller
+        uninst:
+            ExecWait '$R0 _?=$R1'
+            
+        done:
+            # Checking installed JRE
+            Call CheckInstalledJRE
+            StrCpy $JAVA_HOME_DIR "$JREPath"
+        
+            # Preparing the uninstall log
+            !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
+    FunctionEnd
+
+    #
+    # </onInit>
+    #
+    
+    #
+    # <onInstSuccess>
+    #
+    
+    Function .onInstSuccess
+         # Updating the uninstall log
+         !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
+    FunctionEnd
+    
+    #
+    # </onInstSuccess>
+    #
+    
+    #
+    # <UN.onInit>
+    #
+    
+    Function UN.onInit 
+         # Begin uninstall
+         !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
+    FunctionEnd
+    
+    #
+    # </UN.onInit>
+    #
+        
+    #
+    # <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>
+    #
+
+    #
+    # <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>
+    #
+    
+    #
+    # <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>
+    #