;-------------------------------- ; ; DC INSTALLATION SCRIPT ; ;Include Modern UI !include "MUI2.nsh" !include LogicLib.nsh !include "FileFunc.nsh" !include "WinVer.nsh" !include "WordFunc.nsh" !include "nsDialogs.nsh" !include "LogicLib.nsh" !include "DotNetVer.nsh" !include "x64.nsh" !include "Registry.nsh" ;-------------------------------- ; Ensure the installer is run as an administrator ; RequestExecutionLevel admin AllowRootDirInstall true # define the directory to install to e.g. SBSERVER2 # !define PROGNAME "DC" !define PROGVERSION 1.00 !define PROGINSTALLERNAME "${PROGNAME}" !define DatabaseConectorExeName "Dc" ;------------------------------------------------------------------------------------- ; Set installer file name ; ; define the name of the installer outfile "${PROGINSTALLERNAME}.exe" ;------------------------------------------------------------------------------------- ; this command sets the value for $INSTDIR this must be SEABERTH2 ; InstallDir "$PROGRAMFILES\${PROGNAME}${PROGVERSION}" ; Sets the text that is shown (by default it is 'Nullsoft Install System vX.XX') ; at the bottom of the install window. ; BrandingText " DC" ;-------------------------------- ; General ; ; Name is a reserved word which is used by startup shortcut ; Name "${PROGNAME} ${PROGVERSION} Service" Var BackButton Var BackButtonEnabled Var cirItemInstalled Var InstalledItemCount Var LangSelect Var LocalServiceName Var NextButton Var ServiceConfigDiag Var ServiceName Var ServiceNameCheckBtn Var ServiceNameLabel Var ServiceNameTextBox Var ServiceNameTextBoxPrevVal Var ServiceProcess Var StartMenuFolder Var ValidServiceNameLabel1 Var ValidServiceNameLabel2 Var ServerConfigFile Var ServerExeName Var ServerExePath Var DcExePath ;-------------------------------- ;-------------------------------- ;Service Settings !define ServiceProc "DcService.exe" ;-------------------------------- ;-------------------------------- ;Interface Settings !define MUI_HEADERIMAGE !define MUI_ICON ".\DbConnIcon.ico" !define MUI_HEADERIMAGE_BITMAP ".\Logo.png" !define MUI_ABORTWARNING !define MUI_PAGE_HEADER_TEXT "DC ${PROGVERSION}" ;-------------------------------- ;Pages !insertmacro MUI_PAGE_COMPONENTS Page custom ServiceConfigPage ServiceConfigPageLeave !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_COMPONENTS !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;DC installation section, any DC application specific items ; section "DC" secDc ; check if folder already exists and if so give user a bail out MB IfFileExists "$INSTDIR\Dc.exe" FolderPresent CarryOn FolderPresent: sageBox MB_YESNO|MB_ICONQUESTION "DC already exists $\r Do you want to continue?" IDYES CarryOn IDNO Abandon Abandon: Quit CarryOn: call InstallDc call CheckDotNetVersion call CreateServiceRegEntries ; Switch to "all users of this computer" mode before installing shortcuts SetShellVarContext all ; All components installed write the uninstaller. ; WriteUninstaller $INSTDIR\uninstaller.exe # Make the directory "$INSTDIR" read write accessible by all users AccessControl::SetOnFile "$INSTDIR" "BUILTIN\USERS" "FullAccess" sectionEnd section "un.Dc" secUnDc ;Read the cir reg key to see if the DC component has been installed. ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 ReadRegDWORD $0 HKLM "Software\cir\Dc\${PROGVERSION}\$R0" "DcInstall" ${If} $0 == 1 ;Call application removal function call un.UninstallDc IntOp $InstalledItemCount $InstalledItemCount - 1 ${Else} ;Component not installed no need to uninstall. sageBox MB_OK|MB_ICONSTOP "DC not installed." ${EndIf} sectionEnd ;Descriptions ;Install language strings LangString DESC_secDc ${LANG_ENGLISH} "Installs the DC software." LangString DESC_secNETFramework ${LANG_ENGLISH} "Installs the .NET Framework." ;Uninstall language strings LangString DESC_secUnDc ${LANG_ENGLISH} "DC application." ;Assign language strings to install sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${secDc} $(DESC_secDc) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;Assign language strings to uninstall sections !insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${secUnDc} $(DESC_secUnDc) !insertmacro MUI_UNFUNCTION_DESCRIPTION_END ;Installer callback functions ;This callback will be called when the installer is nearly finished initializing. Function .onInit ;Initialise script variables ; Push 0 Pop $cirItemInstalled Push 0 Pop $InstalledItemCount SetOutPath $TEMP SetRebootFlag true ; Set the default language to English ; StrCpy $LangSelect "English" SectionSetSize ${secDc} 93500.0 StrCpy $ServiceNameTextBoxPrevVal "DC Service" StrCpy $ServiceProcess ${ServiceProc} FunctionEnd Function un.onInit ;Search the cir registry key for installed items ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 SetRebootFlag true ; Has DC been installed? ReadRegDWORD $0 HKLM "Software\cir\Dc\${PROGVERSION}\$R0" "DcInstall" ${If} $0 == 1 IntOp $InstalledItemCount $InstalledItemCount + 1 ${EndIf} FunctionEnd ;This callback is called when the install was successful. Function .onInstSuccess ; Create an entry for DC in the installed programs section of the ; registry so an entry is added to the add/remove programs dialogue. ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "DisplayName" "${PROGNAME} ${PROGVERSION} ($INSTDIR)" ; Add uninstaller to add/remove programs WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "UninstallString" "$INSTDIR\uninstaller.exe" ; Add the path for the uninstall icon WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "DisplayIcon" "$INSTDIR\DbConnIcon.ico" ; Add publisher name WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "Publisher" "cir log" ; Add version WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "DisplayVersion" "${PROGVERSION}" ; Add help link WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0\" "HelpLink" "" FunctionEnd ;This callback is called when the uninstall was successful. Right before the ;install window closes (which may be after the user clicks 'Close' if ;SetAutoClose is set to false). Function un.onUninstSuccess ${If} $InstalledItemCount == 0 ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 ;All components uninstalled remove entry from 'add/remove programs' ;and clean up the registry. DeleteRegKey HKLM "Software\cir\Dc\${PROGVERSION}\$R0" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGNAME} ${PROGVERSION} $R0" ${EndIf} FunctionEnd Function InstallDc ;Copy DC related files - set the outpath and use File command to get content SetOutPath $INSTDIR StrCpy $DcExePath $INSTDIR ;we need to removve the \ characters from path name because this confuses subsequent use ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 File /r /x *.pdb /x *.vshost.exe /x *.vshost.exe.config /x *.vshost.exe.manifest "..\Dc\bin\release\*.*" File /x *.pdb /x *.vshost.exe /x *.vshost.exe.config /x *.vshost.exe.manifest "..\DcService\bin\Release\DcService.exe" File ".\DbConnIcon.ico" ;Record the installation of the SEABERTH Server software use the cir registry key WriteRegDWORD HKLM "Software\cir\Dc\${PROGVERSION}\$R0" "DcInstall" 1 Push 1 Pop $cirItemInstalled FunctionEnd Function un.UninstallDc ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 ; Stop the DC service ; ReadRegStr $LocalServiceName HKLM "Software\cir\Dc\${PROGVERSION}\$R0" "ServiceName" SimpleSC::StopService "$LocalServiceName" 0 Pop $0 ${If} $0 != 0 ;Failed to stop the Datanase Connector service ; Push $0 SimpleSC::GetErrorsage Pop $0 sageBox MB_YESNO "Failed to stop $LocalServiceName service - Reason: $0 $\n$\n Do you wish to continue with the uninstall?" IDYES continue IDNO stop ${Else} goto continue ${EndIF} stop: Abort continue: ;Remove service entries from the registry DeleteRegKey HKLM "System\CurrentControlSet\services\$LocalServiceName" DeleteRegKey HKLM "System\CurrentControlSet\services\eventlog\Application\$LocalServiceName" DeleteRegKey HKLM "SYSTEM\CurrentControlSet\service\eventlog\SEABERTH Log\$ServiceName" ;Remove the SEABERTH Server program folder and sub folders RMDir /r $INSTDIR ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 ; Remove registry key(s) DeleteRegKey HKLM "Software\cir\Dc\${PROGVERSION}\$R0" DeleteRegKey HKLM "Software\cir\Dc\${PROGVERSION}" DeleteRegKey HKLM "Software\cir\Dc" FunctionEnd ;--------------------------------------------------------------------------------- ;Custom page functions Function ServiceConfigPage ;Create a dialoge for the custom page nsDialogs::Create 1018 Pop $ServiceConfigDiag ${If} $ServiceConfigDiag == error Abort ${EndIf} !insertmacro MUI_HEADER_TEXT "Enter Service Name" "Enter a name for the service controlling the DC" ; Retrieve the windows handle to the next button ; GetDlgItem $NextButton $HWNDPARENT 1 ; next=1, cancel=2, back=3 EnableWindow $NextButton 0 GetDlgItem $BackButton $HWNDPARENT 3 ; next=1, cancel=2, back=3 EnableWindow $BackButton $BackButtonEnabled ; Add controls to the page namely a text box for the installer to enter a defualt name for the ; service or for the user to create their own. ; ${NSD_CreateLabel} 2% 0% 100% 12u "The service name must be unique. Once you have entered the name, click the Validate" Pop $ValidServiceNameLabel1 ${NSD_CreateLabel} 2% 8% 100% 12u "name button. The installer will check that the name is valid." Pop $ValidServiceNameLabel2 ${NSD_CreateLabel} 20% 40% 100% 12u "Enter service name:" Pop $ServiceNameLabel ${NSD_CreateText} 20% 50% 60% 20u $ServiceNameTextBoxPrevVal Pop $ServiceNameTextBox ${NSD_OnChange} $ServiceNameTextBox nsDialogsPageTextChange ${NSD_CreateButton} 40% 70% 20% 20u "Validate name" Pop $ServiceNameCheckBtn GetFunctionAddress $0 ValidateServiceName nsDialogs::OnClick $ServiceNameCheckBtn $0 ; Show the custom page this is a block call which will not return until Back, Next or Cancel is pressed. ; nsDialogs::Show FunctionEnd Function nsDialogsPageTextChange ;if the text of the service name box has changed, disable the next button so validation is needed again EnableWindow $NextButton 0 FunctionEnd Function ValidateServiceName ;pop controls HWND from the stack Pop $1 ${If} $1 == $ServiceNameCheckBtn ;Read service name from textbox control ${NSD_GetText} $ServiceNameTextBox $ServiceNameTextBoxPrevVal ;Search the registry for a service with this name registry::Open /NOUNLOAD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\" "/K=1 /V=1 /S=0 /B=1 /N='$ServiceNameTextBoxPrevVal'" .r0 StrCmp $0 -1 error registry::Find /NOUNLOAD .r1 .r2 .r3 .r4 ${If} $4 == '' sageBox MB_OK "Valid service name entered!" EnableWindow $NextButton 1 StrCpy $ServiceName $ServiceNameTextBoxPrevVal ;Retrieve the windows handle to the back button (this button will be disabled once the validation has been done) EnableWindow $BackButton 0 Push 0 Pop $BackButtonEnabled goto close ${Else} sageBox MB_OK "Service <$ServiceNameTextBoxPrevVal> already exsists.$\n$\nPlease enter a different name." goto close ${EndIf} error: sageBox MB_OK "Failed to open registry" close: registry::Close ${EndIf} FunctionEnd Function ServiceConfigPageLeave ; Record the current service name ${NSD_GetText} $ServiceNameTextBox $ServiceNameTextBoxPrevVal StrCpy $ServiceName $ServiceNameTextBoxPrevVal FunctionEnd Function CreateServiceRegEntries ; Add an entry for the DC service in the registry ; Pror to this point the installer will have checked to make sure the chosen name ; doesn't conflict with any previous entry WriteRegStr HKLM "System\CurrentControlSet\services\$ServiceName" "DisplayName" "$ServiceName" WriteRegDWORD HKLM "System\CurrentControlSet\services\$ServiceName" "ErrorControl" "0x00000001" ${WordReplace} "$ServiceName" " " "_" "+" $R0 WriteRegExpandStr HKLM "System\CurrentControlSet\services\$ServiceName" "ImagePath" "$\"$DcExePath\${ServiceProc}$\" $\"$DcExePath\\$\" $\"${DatabaseConectorExeName}.exe$\" $\"Pipe$R0$\"" WriteRegStr HKLM "System\CurrentControlSet\services\$ServiceName" "ObjectName" "LocalSystem" WriteRegDWORD HKLM "System\CurrentControlSet\services\$ServiceName" "Start" "0x00000003" WriteRegDWORD HKLM "System\CurrentControlSet\services\$ServiceName" "Type" "0x00000010" ; Write service name to DC install registry key or use by uninstaller ${WordReplace} "$INSTDIR" "\" "-" "+" $R0 WriteRegStr HKLM "Software\cir\Dc\${PROGVERSION}\$R0" "ServiceName" "$ServiceName" FunctionEnd Function CreateEventLogEntry ; Run the DC service event log configuration until. SetOutPath $TEMP DetailPrint "Building DC Service Eventlog Entry" File "..\DBConnectorEventLogConfig\bin\release\DBConnectorEventLogConfig.exe" ExecWait "$TEMP\DBConnectorEventLogConfig.exe" DetailPrint "Cleaning up" Delete $TEMP\ConfigSEABERTHEventlog.exe FunctionEnd Function CheckDotNetVersion ;Check for the installation of the .NET Framework version 4.5 ;.net 4.5 is an extension too .net 4.0 so need to check for 4.0 as well. ;https://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Release IntCmp $0 378389 is45 isbelow45 is45 isbelow45: ; Check for .net 4.0 ${If} ${HasDotNet4.0} ;Only need to install .net 4.5 extension update to .net 4.0. push 1 ${Else} ;Install .net 4.0 and also .net 4.5 extension. push 0 ${EndIf} ;Installl the .Net framework V4.5 and any servicepacks ; sageBox MB_OK|MB_ICONSTOP ".NET runtime library is not installed. The .NET installer will now run. $\rAfter .NET has been installed, installation of DC will resume." call InstallDotNET call CreateEventLogEntry is45: ;.Net framework 4.5 or above is installed. call CreateEventLogEntry Return FunctionEnd Function InstallDotNET SetOutPath $TEMP pop $0 ${If} $0 == 0 ;Install both .net 4.0 and .net 4.5. File ".\.NET Frameworks\dotNetFx40_Full_x86_x64.exe" DetailPrint "Installing .NET framework v4.0" ExecWait "$TEMP\dotNetFx40_Full_x86_x64.exe /q:a /c:$\"install /q$\"" DetailPrint "Cleaning up" Delete $TEMP\dotNetFx40_Full_x86_x64.exe File ".\.NET Frameworks\dotNetFx45_Full_setup.exe" DetailPrint "Installing .NET framework v4.5" ExecWait "$TEMP\dotNetFx45_Full_setup.exe /q:a /c:$\"install /q$\"" DetailPrint "Cleaning up" Delete $TEMP\dotNetFx45_Full_setup.exe ${ElseIf} $0 == 1 ;Install .net 4.5 extension. File ".\.NET Frameworks\dotNetFx45_Full_setup.exe" DetailPrint "Installing .NET framework v4.5" ExecWait "$TEMP\dotNetFx45_Full_setup.exe /q:a /c:$\"install /q$\"" DetailPrint "Cleaning up" Delete $TEMP\dotNetFx45_Full_setup.exe ${EndIf} FunctionEnd