# This installs two files, app.exe and logo.ico, creates a start menu shortcut, builds an uninstaller, and # adds uninstall information to the registry for Add/Remove Programs # To get started, put this script into a folder with the two files (app.exe, logo.ico, and license.rtf - # You'll have to create these yourself) and run makensis on it # If you change the names "app.exe", "logo.ico", or "license.rtf" you should do a search and replace - they # show up in a few places. # All the other settings can be tweaked by editing the !defines at the top of this script !define APPNAME "Winify" !define COMPANYNAME "Wizardry and Steamworks" !define DESCRIPTION "Control computer power state after an user-configurable timeout." # These will be displayed by the "Click here for support information" link in "Add/Remove Programs" # It is possible to use "mailto:" links in here to open the email client !define HELPURL "http://winify.grimore.org/" # "Support Information" link !define UPDATEURL "http://winify.grimore.org/download/" # "Product Updates" link !define ABOUTURL "http://grimore.org/" # "Publisher" link # This is the size (in kB) of all the files copied into "Program Files" #!define INSTALLSIZE 7233 #### General Use Functions ## Get version of an exe file. Function GetFileVersion !define GetFileVersion `!insertmacro GetFileVersionCall` !macro GetFileVersionCall _FILE _RESULT Push `${_FILE}` Call GetFileVersion Pop ${_RESULT} !macroend Exch $0 Push $1 Push $2 Push $3 Push $4 Push $5 Push $6 ClearErrors GetDllVersion '$0' $1 $2 IfErrors error IntOp $3 $1 >> 16 IntOp $3 $3 & 0x0000FFFF IntOp $4 $1 & 0x0000FFFF IntOp $5 $2 >> 16 IntOp $5 $5 & 0x0000FFFF IntOp $6 $2 & 0x0000FFFF StrCpy $0 '$3.$4.$5.$6' goto end error: SetErrors StrCpy $0 '' end: Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Exch $0 FunctionEnd ## Explode !include "LogicLib.nsh" !define Explode "!insertmacro Explode" Function Explode !macro Explode Length Separator String Push `${Separator}` Push `${String}` Call Explode Pop `${Length}` !macroend ; Initialize variables Var /GLOBAL explString Var /GLOBAL explSeparator Var /GLOBAL explStrLen Var /GLOBAL explSepLen Var /GLOBAL explOffset Var /GLOBAL explTmp Var /GLOBAL explTmp2 Var /GLOBAL explTmp3 Var /GLOBAL explArrCount ; Get input from user Pop $explString Pop $explSeparator ; Calculates initial values StrLen $explStrLen $explString StrLen $explSepLen $explSeparator StrCpy $explArrCount 1 ${If} $explStrLen <= 1 ; If we got a single character ${OrIf} $explSepLen > $explStrLen ; or separator is larger than the string, Push $explString ; then we return initial string with no change Push 1 ; and set array's length to 1 Return ${EndIf} ; Set offset to the last symbol of the string StrCpy $explOffset $explStrLen IntOp $explOffset $explOffset - 1 ; Clear temp string to exclude the possibility of appearance of occasional data StrCpy $explTmp "" StrCpy $explTmp2 "" StrCpy $explTmp3 "" ; Loop until the offset becomes negative ${Do} ; If offset becomes negative, it is time to leave the function ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|} ; Remove everything before and after the searched part ("TempStr") StrCpy $explTmp $explString $explSepLen $explOffset ${If} $explTmp == $explSeparator ; Calculating offset to start copy from IntOp $explTmp2 $explOffset + $explSepLen ; Offset equals to the current offset plus length of separator StrCpy $explTmp3 $explString "" $explTmp2 Push $explTmp3 ; Throwing array item to the stack IntOp $explArrCount $explArrCount + 1 ; Increasing array's counter StrCpy $explString $explString $explOffset 0 ; Cutting all characters beginning with the separator entry StrLen $explStrLen $explString ${EndIf} ${If} $explOffset = 0 ; If the beginning of the line met and there is no separator, ; copying the rest of the string ${If} $explSeparator == "" ; Fix for the empty separator IntOp $explArrCount $explArrCount - 1 ${Else} Push $explString ${EndIf} ${EndIf} IntOp $explOffset $explOffset - 1 ${Loop} Push $explArrCount FunctionEnd Function GetAppVersion ; Create global variables. Var /GLOBAL VERSIONMAJOR Var /GLOBAL VERSIONMINOR Var /GLOBAL VERSIONBUILD ; Initialize global variables. StrCpy $VERSIONMAJOR 1 StrCpy $VERSIONMINOR 0 StrCpy $VERSIONBUILD 0 ; Retrieve executable version. ${GetFileVersion} "${APPNAME}.exe" $R0 ${Explode} $0 "." $R0 Pop $0 Pop $VERSIONMAJOR Pop $VERSIONMINOR Pop $VERSIONBUILD FunctionEnd RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on) InstallDir "$PROGRAMFILES\${COMPANYNAME}\${APPNAME}" # rtf or txt file - remember if it is txt, it must be in the DOS text format (\r\n) LicenseData "LICENSE.txt" # This will be in the installer/uninstaller's title bar Name "${APPNAME}" Icon "${APPNAME}.ico" # Set the output file. outFile "${APPNAME}.exe" !include LogicLib.nsh !include nsDialogs.nsh # Just three pages - license agreement, install location, and installation page custom nsDialogsImage page license page directory Page instfiles !macro VerifyUserIsAdmin UserInfo::GetAccountType pop $0 ${If} $0 != "admin" ;Require admin rights on NT4+ messageBox mb_iconstop "Administrator rights required!" setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED quit ${EndIf} !macroend function .onInit InitPluginsDir setShellVarContext all !insertmacro VerifyUserIsAdmin File /oname=$PLUGINSDIR\image.bmp "wasinstallerlogo.bmp" # Get the application version. Call GetAppVersion functionEnd Var Dialog Var Image Var ImageHandle Function nsDialogsImage nsDialogs::Create 1018 Pop $Dialog ${If} $Dialog == error Abort ${EndIf} ${NSD_CreateBitmap} 0 0 100% 100% "" Pop $Image ${NSD_SetImage} $Image $PLUGINSDIR\image.bmp $ImageHandle nsDialogs::Show ${NSD_FreeImage} $ImageHandle FunctionEnd section "install" # Files for the install directory - to build the installer, these should be in the same directory as the install script (this file) setOutPath $INSTDIR # Files added here should be removed by the uninstaller (see section "uninstall") file /r "bin\Release\*.*" file "${APPNAME}.ico" # Add any other files for the install directory (license files, app data, etc) here # Uninstaller - See function un.onInit and section "uninstall" for configuration writeUninstaller "$INSTDIR\uninstall.exe" # Create start-menu items CreateDirectory "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}" CreateShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}\uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 CreateShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\${APPNAME}.exe" "" "$INSTDIR\${APPNAME}.ico" # Create desktop shortcut CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\${APPNAME}.exe" "" # Registry information for add/remove programs WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${APPNAME}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$\"$INSTDIR$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\${APPNAME}.ico$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "$\"${COMPANYNAME}$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "HelpLink" "$\"${HELPURL}$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "$\"${UPDATEURL}$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "$\"$VERSIONMAJOR.$VERSIONMINOR.$VERSIONBUILD$\"" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" $VERSIONMAJOR WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" $VERSIONMINOR # There is no option for modifying or repairing the install WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair" 1 # Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size #WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE} sectionEnd # Uninstaller function un.onInit SetShellVarContext all #Verify the uninstaller - last chance to back out MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next Abort next: !insertmacro VerifyUserIsAdmin functionEnd section "uninstall" # Remove desktop shortcut delete "$DESKTOP\${APPNAME}.lnk" # Remove Start Menu items delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}\uninstall.lnk" delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}\${APPNAME}.lnk" # Try to remove the Start Menu folder for the program. # NB: This will only happen if it is empty rmDir "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}" # Try to remove the Start Menu folder for the company. rmDir "$SMPROGRAMS\${COMPANYNAME}" # Remove files rmDir /r "$INSTDIR\*.*" # Always delete uninstaller as the last action delete $INSTDIR\uninstall.exe # Try to remove the install directory - this will only happen if it is empty rmDir $INSTDIR # Remove uninstaller information from the registry DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" sectionEnd