Archive: Readme page for the modern UI


Readme page for the modern UI
Hi,

I'm new to NSIS. I started using it yesterday, I chose the modern UI, but there's something I can't find: a readme page. Is it possible to include a readme page in a modern UI? If yes, how?

Thanks in advance,

Pieter De Decker


If you launch the main NSIS menu, there is a link to the ModernUI Readme. Or you can browse to it--it's location is ${NSISDIR}\docs\ModernUI\Readme.html


Or, to answer his question, you would have to make a custom page using installoptions, and use my CustomLicense plug-in to display the text from the readme in it.


D'OH! Sorry pdedecker! I thought you were asking where the readme for MUI was, not how to insert a readme page! :o

(Thanks JasonFriday!)


I already figured out how to use custom pages, but every time I make a change to my readme file (let's just say readme.txt), I have to change it in the custom page too. Does this CustomLicense plug-in allow you to display a .txt?


Yes, thats one of the points of this plugin. The other point is to get around the 1024 char length limit on NSIS strings.

It loads a .txt file into the specified hwnd. When using MUI, use it in the show function. When using classic, initialise the page, pop the hwnd off the stack, then get the hwnd of the control you want the text to go into using GetDlgItem, then set the text using the show function in the CustomLicense plug-in. Example:

; For MUI:
Function CustomShow
; read the installoptions readme on getting the field num.
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\license.txt" "$0"
FunctionEnd

; For classic:
Function CustomPre
InstallOptions::init "$PLUGINSDIR\custompage.ini"
Pop $0
; read the installoptions readme on getting the field num.
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\license.txt" "$0"
InstallOptions::show
FunctionEnd

I embedded the code in my script, but it doesn't show my readme. Why?

; USBsyncer-0.3.nsi
;
; This script is based on example1.nsi, but it remembers the directory,
; has uninstall support and (optionally) installs start menu shortcuts.
;
; It will install example2.nsi into a directory that the user selects,

;--------------------------------
;Include Modern UI

!include "MUI.nsh"

;--------------------------------

; The name of the installer
Name "USBsyncer v0.3"
XPStyle on
ShowInstDetails show
ShowUninstDetails show

ReserveFile "ReadmePage.ini"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
!define MUI_FINISHPAGE_SHOWREADME "readme.txt"
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Show Readme (recommended)"
!define MUI_FINISHPAGE_RUN "$INSTDIR\USBsyncer.exe"
!define MUI_FINISHPAGE_RUN_TEXT "Run USBsyncer"
!define MUI_FINISHPAGE_LINK "USBsyncer Homepage"
!define MUI_FINISHPAGE_LINK_LOCATION "http://usbsyncer.ueuo.com/"

; The file to write
OutFile "../Installer Builds/USBsyncer-output.exe"

; The default installation directory
InstallDir "$PROGRAMFILES\USBsyncer v0.3\"

; Registry key to check for directory (so if you install again, it will
; overwrite the old one automatically)
; InstallDirRegKey HKLM "Software\NSIS_Example2" "Install_Dir"

;--------------------------------

!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_RIGHT
!define MUI_WELCOMEFINISHPAGE_BITMAP "header_left.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "header_left.bmp"
!define MUI_HEADERIMAGE_BITMAP "header.bmp"
!define MUI_ABORTWARNING
!define MUI_UNABORTWARNING

Function .onInit
# the plugins dir is automatically deleted when the installer exits
InitPluginsDir
File /oname=$PLUGINSDIR\splash.bmp "splash.bmp"
#optional
#File /oname=$PLUGINSDIR\splash.wav "C:\myprog\sound.wav"

advsplash::show 5000 600 400 -1 $PLUGINSDIR\splash

Pop $0 ; $0 has '1' if the user closed the splash screen early,
; '0' if everything closed normally, and '-1' if some error occurred.

Delete $PLUGINSDIR\splash.bmp
!insertmacro MUI_INSTALLOPTIONS_EXTRACT_AS "ReadmePage.ini" "ReadmePage.ini"
ReadRegStr $0 HKLM Software\USBsyncer\ "InstallDir"
IfErrors 0 +2
ReadRegStr $0 HKLM Software\MediaSync\ "InstallDir"
IfFileExists $0\MediaSync.exe 0 +6
MessageBox MB_OK "An old version of USBsyncer or MediaSync seems to be installed. Press OK to run its uninstaller."
IfFileExists $0\Uninstall.exe 0 +2
ExecWait '"$0\Uninstall.exe"'
IfFileExists $0\Setup.exe 0 +2
ExecWait '"$0\Setup.exe" /remove'
IfFileExists $0\USBsyncer.exe 0 +6
MessageBox MB_OK "An old version of USBsyncer or MediaSync seems to be installed. Press OK to run its uninstaller."
IfFileExists $0\Uninstall.exe 0 +2
ExecWait '"$0\Uninstall.exe"'
IfFileExists $0\Setup.exe 0 +2
ExecWait '"$0\Setup.exe" /remove'

FunctionEnd

;--------------------------------

; Pages

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "license.txt"
Page custom CustomShow
Page custom ReadmePage
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_COMPONENTS
!insertmacro MUI_UNPAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"

;--------------------------------

; Readme

LangString TEXT_IO_TITLE ${LANG_ENGLISH} "USBsyncer Information"
LangString TEXT_IO_SUBTITLE ${LANG_ENGLISH} "Please read this to learn more about the way USBsyncer works."

Function ReadmePage

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_DISPLAY "ReadmePage.ini"

FunctionEnd

Function CustomShow
; read the installoptions readme on getting the field num.
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "readme.txt" "$0"
FunctionEnd

;--------------------------------

; License

LicenseData license.txt
LicenseForceSelection checkbox

;--------------------------------

; The stuff to install

InstType "Full (recommended)"
InstType "Minimal"

Section "USBsyncer Core" Core

SectionIn RO 1 2

; Set output path to the installation directory.
SetOutPath $INSTDIR

; Files in the root dir
File "USBsyncer.exe"
File "readme.txt"
File "license.txt"

; Files in the bin dir
SetOutPath $INSTDIR\bin
File "bin\USBwatcher.exe"

; Files in the images dir
SetOutPath $INSTDIR\images
File "images\appheader.gif"
File "images\busy.ico"
File "images\idle.ico"

; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\USBsyncer "Install_Dir" "$INSTDIR"

; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "DisplayName" "USBsyncer"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "NoRepair" 1
WriteUninstaller "uninstall.exe"

SectionEnd

Section "USBsyncer Updater" Updater

SectionIn 1

; Set output path to the installation directory.
SetOutPath $INSTDIR

; Put file there
File "USBupdater.exe"

; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\USBsyncer "Install_Dir" "$INSTDIR"

; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "DisplayName" "USBsyncer"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3" "NoRepair" 1
WriteUninstaller "uninstall.exe"

SectionEnd

Section "Start with Windows" EnableOnBootup

SectionIn 1 2

CreateShortCut "$SMSTARTUP\USBsyncer.lnk" "$INSTDIR\USBsync.exe" "" "$INSTDIR\USBsync.exe" 0

SectionEnd

Section "Start Menu Shortcuts" Shortcuts

SectionIn 1 2

CreateDirectory "$SMPROGRAMS\USBsyncer v0.3"
CreateShortCut "$SMPROGRAMS\USBsyncer v0.3\Start USBsyncer v0.3.lnk" "$INSTDIR\USBsyncer.exe" "" "$INSTDIR\USBsyncer.exe" 0
CreateShortCut "$SMPROGRAMS\USBsyncer v0.3\Synchronize and quit.lnk" "$INSTDIR\USBsyncer.exe" "/syncandquit" "$INSTDIR\USBsyncer.exe" 0
CreateShortCut "$SMPROGRAMS\USBsyncer v0.3\Uninstall USBsyncer v0.3.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0

SectionEnd

;--------------------------------
; Other stuff


;--------------------------------

; Uninstaller

Section "un.USBsyncer" unProgram

SectionIn RO

; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\USBsyncer0.3"
DeleteRegKey HKLM SOFTWARE\USBsyncer

; Remove files and uninstaller
Delete $INSTDIR\USBsyncer.exe
Delete $INSTDIR\USBupdater.exe
Delete $INSTDIR\license.txt
Delete $INSTDIR\readme.txt
Delete $INSTDIR\Uninstall.exe
Delete $INSTDIR\bin\*.*
Delete $INSTDIR\images\*.*
RMDir "$INSTDIR\bin\"
RMDir "$INSTDIR\images\"

; Remove shortcuts, if any
Delete "$SMPROGRAMS\USBsyncer v0.3\*.*"
Delete "$SMSTARTUP\USBsyncer.lnk"

; Remove Start Menu folder
RMDir "$SMPROGRAMS\USBsyncer v0.3\"

SectionEnd

Section "un.Delete settings" unPrgrmFldr

RMDir "$INSTDIR"

SectionEnd

;--------------------------------

;Descriptions

; Installer component description strings
LangString DESC_Core ${LANG_ENGLISH} "The main component of USBsyncer."
LangString DESC_Updater ${LANG_ENGLISH} "A simple updater to check for new versions."
LangString DESC_EnableOnBootup ${LANG_ENGLISH} "This is required for USBsyncer to work properly."
LangString DESC_Shortcuts ${LANG_ENGLISH} "Creates shortcuts for USBsyncer."

; Same for uninstaller
LangString DESC_unProgram ${LANG_ENGLISH} "Uninstall USBsyncer and all its components."
LangString DESC_unPrgrmFldr ${LANG_ENGLISH} "Remove the USBsyncer program directory and settings."

; Link strings to installer components
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Core} $(DESC_Core)
!insertmacro MUI_DESCRIPTION_TEXT ${Updater} $(DESC_Updater)
!insertmacro MUI_DESCRIPTION_TEXT ${EnableOnBootup} $(DESC_EnableOnBootup)
!insertmacro MUI_DESCRIPTION_TEXT ${Shortcuts} $(DESC_Shortcuts)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

; Once again, same for uninstaller
!insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${unProgram} $(DESC_unProgram)
!insertmacro MUI_DESCRIPTION_TEXT ${unPrgrmFldr} $(DESC_unPrgrmFldr)
!insertmacro MUI_UNFUNCTION_DESCRIPTION_END

;--------------------------------
(you can ignore the double readme page)

This line should specify a full path:


!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\readme.txt"

You have to extract your readme to the $PLUGINSDIR in order to show it:


Function .onInit
# the plugins dir is automatically deleted when the installer exits
InitPluginsDir
File /oname=$PLUGINSDIR\splash.bmp "splash.bmp"
#optional
#File /oname=$PLUGINSDIR\splash.wav "C:\myprog\sound.wav"

File /oname=$PLUGINSDIR\readme.txt "readme.txt"

Next is pages:

; Pages

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "license.txt"
Page custom ReadmePage
!insertmacro MUI_PAGE_DIRECTORY
Now, the function is what actually shows the page. You only need one function to show the page.

Function ReadmePage

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW

FunctionEnd

Did I forget something?

Edit: I did the

!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\readme.txt"
thingy, but it still doesn't work.

You forgot to pop the HWND after MUI_INSTALLOPTIONS_INITDIALOG. You use $MUI_HWND, but it has an incorrect and outdated value. This makes CustomLicense::LoadFile fail, because it tries to set the text to the wrong window.


I'm sorry, I still don't get it. You see, I'm still very new to this 'programming language'. Can you post the right code please? :)


Function ReadmePage

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
Pop $MUI_HWND
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW

FunctionEnd

Didn't work. Strange.


Are you sure you're using the correct id for GetDlgItem? You should use the new HWND field in the INI instead, it's much simpler. Assuming the text field is really [Field 2], use:

!insertmaro MUI_INSTALLOPTIONS_READ $0 ReadmePage.ini "Field 2" HWND

Do I have to insert that line in the Readme function, like this?

Function Readme
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
!insertmacro MUI_INSTALLOPTIONS_READ $0 ReadmePage.ini "Field 1" HWND
Pop $MUI_HWND
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
By the way, my .ini looks like this:
[Settings]
NumFields=1

[Field 1]
Type=text
Left=0
Right=-1
Top=0
Bottom=125
flags=MULTILINE|VSCROLL|READONLY
HWND="text goes here"

Almost, it comes instead of GetDlgItem.

Function Readme
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
!insertmacro MUI_INSTALLOPTIONS_READ $0 ReadmePage.ini "Field 1" HWND
Pop $MUI_HWND
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
Just for your information, the GetDlgItem line was indeed incorrect. You tried to get the HWND of Field 2, which doesn't exist.

Originally posted by kichik
[B]Almost, it comes instead of GetDlgItem.
But you first said it was:
Function ReadmePage

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
Pop $MUI_HWND
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW

FunctionEnd
I can't know such things after a week, can I? :)

Anyway, I will try your new code asap.

Edit: it's 100% working.

Good to see it works. Always here to help.