I want to create a custom silent mode which display only the license.
For exemple, I have tested this :
!define MUI_PAGE_CUSTOMFUNCTION_PRE skipPage
!insertmacro MUI_PAGE_WELCOME
Function skipPage
${GetOptions} $CMDLINE "--quiet" $0
${If} $0 == "--quiet"
Abort
${EndIf}
FunctionEnd
But the page is not skipped, an idea ?
This has nothing to do with skipping pages, you are simply using ${GetOptions} incorrectly.
The returned variable contains the data after the switch itself. If you just want to detect the switch you should check for errors:
!include FileFunc.nsh
!include LogicLib.nsh
Function skipPage
${GetParameters} $R0
ClearErrors
${GetOptions} $R0 "--quiet" $0
${IfNot} ${Errors}
Abort
${EndIf}
FunctionEnd
Related
I am new to NSIS. I am trying to add this below style of the page in post-installation (i.e. before the finish page). Could anyone suggest, whether we can do a single custom page and add the necessary checkbox, radio button, and program groups ? or any other suggestions.
Below is my page sequence:
!insertmacro MUI_PAGE_DIRECTORY
;Custom page for selecting service name to restart.
Page custom nsDialogsSelectService ngDialogSelectServicePageLeave
; variable and text for the app data dir
!define MUI_DIRECTORYPAGE_VARIABLE $appDataDir
!define MUI_PAGE_HEADER_TEXT "Choose Data Directory"
!define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install application data for ${PRODUCT_FULL} ${PVERSION}."
!define MUI_DIRECTORYPAGE_TEXT_TOP "Setup will install data directory need todo. To install in a different folder, click Browse and select another folder. Click Next to Continue."
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Destination Folder"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_TITLE_3LINES
Page custom nsDialogShortcut ngDialogShortcutPageLeave ;Page contain checkbox , based on the selection of checkbox I am showing Startmenu and then finish page.
!insertmacro MUI_PAGE_STARTMENU 0 $SMDir
!insertmacro MUI_PAGE_FINISH
Giving the user the choice of user/machine shortcuts is in conflict with how UAC works. When a non-admin user elevates with an administrator account the installer will end up running with the "wrong" profile.
The Windows guidelines say that only application suites (with individual major applications, like MS Office) should create Start menu folders. Regular applications should create their (single) shortcut directly in $SMPrograms. You should not create shortcuts to the uninstaller nor help-files. You should also refrain from creating a desktop shortcut.
This means you can simply use the components page to provide the shortcut option(s):
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Section "Program files"
SectionIn RO
SetOutPath $InstDir
File "MyApp.exe"
SectionEnd
Section "Start menu shortcut"
CreateShortcut "$SMPrograms\$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd
Section /o "Desktop shortcut"
CreateShortcut "$Desktop\$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd
or as a checkbox on the Finish page:
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_SHOWREADME ""
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Start menu shortcut"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateShortcuts
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function CreateShortcuts
CreateShortcut "$SMPrograms\$(^Name).lnk" "$InstDir\MyApp.exe"
FunctionEnd
If you actually have a suite of applications then you can use the Start menu page to prompt for a folder name:
Var SMFolder
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE STARTMENU Suite $SMFolder
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Section
!insertmacro MUI_STARTMENU_WRITE_BEGIN Suite
CreateDirectory "$SMPrograms\$SMFolder"
CreateShortcut "$SMPrograms\$SMFolder\App1.lnk" "$InstDir\MyApp1.exe"
CreateShortcut "$SMPrograms\$SMFolder\App2.lnk" "$InstDir\MyApp2.exe"
; TODO: Write $SMFolder to the registry or a .ini so your uninstaller can delete the folder
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
In the unlikely event that you have a suite of applications and you also want to create desktop shortcuts then yes, you need to use a custom page:
Var SMDir
Var SMCheck
Var DeskCheck
Var SMList
Var SMDirEdit
!include LogicLib.nsh
!include nsDialogs.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyShortcutsPageCreate MyShortcutsPageLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function .onInit
StrCpy $SMDir "$(^Name)" ; Default
StrCpy $SMCheck ${BST_CHECKED}
FunctionEnd
Function MyShortcutsPageCreate
!insertmacro MUI_HEADER_TEXT "Shortcuts" "Shortcuts blah blah blah"
nsDialogs::Create 1018
Pop $0
${IfThen} $0 == error ${|} Abort ${|}
${NSD_CreateCheckbox} 0 0u 50% 12u "Create Start menu shortcuts"
Pop $R8
SendMessage $R8 ${BM_SETCHECK} $SMCheck ""
${NSD_CreateCheckbox} 0 14u 50% 12u "Create desktop shortcuts"
Pop $R9
SendMessage $R9 ${BM_SETCHECK} $DeskCheck ""
${NSD_CreateSortedListBox} 0 28u 100% -43u ""
Pop $SMList
${NSD_CreateText} 0 -13u 100% 12u "$SMDir"
Pop $SMDirEdit
${NSD_LB_AddString} $SMList "(Default)"
${NSD_LB_SetItemData} $SMList 0 1 ; Mark as special
SetShellVarContext Current
Call FillSMList
SetShellVarContext All
Call FillSMList
SetShellVarContext ? ; TODO: Restore to what you actually are installing as
${NSD_OnChange} $SMList OnSMListChanged
${NSD_OnClick} $R8 OnSMCheckChanged
Push $R8
Call OnSMCheckChanged
nsDialogs::Show
FunctionEnd
Function FillSMList
FindFirst $0 $1 "$SMPrograms\*"
loop:
StrCmp $1 "" done
${If} ${FileExists} "$SMPrograms\$1\*.*"
${AndIf} $1 != "."
${AndIf} $1 != ".."
${NSD_LB_FindStringExact} $SMList "$1" $2
${If} $2 < 0
${NSD_LB_AddString} $SMList $1
${EndIf}
${EndIf}
FindNext $0 $1
Goto loop
done:
FindClose $0
FunctionEnd
Function OnSMCheckChanged
Pop $0
${NSD_GetChecked} $0 $0
EnableWindow $SMList $0
EnableWindow $SMDirEdit $0
FunctionEnd
Function OnSMListChanged
Pop $0
${NSD_LB_GetSelection} $SMList $0
${NSD_SetText} $SMDirEdit "$0\$(^Name)"
${NSD_LB_GetSelectionIndex} $SMList $0
${NSD_LB_GetItemData} $SMList $0 $0
${If} $0 <> 0
${NSD_SetText} $SMDirEdit "$(^Name)"
${EndIf}
FunctionEnd
Function MyShortcutsPageLeave
${NSD_GetChecked} $R8 $SMCheck
${NSD_GetChecked} $R9 $DeskCheck
${NSD_GetText} $SMDirEdit $SMDir
FunctionEnd
Section
${If} $SMCheck <> 0
CreateDirectory "$SMPrograms\$SMDir"
CreateShortcut "$SMPrograms\$SMDir\App1.lnk" "$InstDir\App1.exe"
CreateShortcut "$SMPrograms\$SMDir\App2.lnk" "$InstDir\App2.exe"
${EndIf}
${If} $DeskCheck <> 0
CreateShortcut "$Desktop\App1.lnk" "$InstDir\App1.exe"
CreateShortcut "$Desktop\App2.lnk" "$InstDir\App2.exe"
${EndIf}
SectionEnd
I have a custom dialog with an "License terms and conditions." checkbox where the Text to the checkbox is actually a link which is suppose to show the License Dialog.
; === LicenseLink (type: Link) ===
${NSD_CreateLink} 132.96u 100.92u 107.29u 14.15u "License terms and conditions."
Pop $hCtl_welcome_LicenseLink
${NSD_OnClick} $hCtl_welcome_LicenseLink ShowLicense
Now in the function "ShowLicense" I tried calling
!insertmacro MUI_PAGE_LICENSE
but get an error:
Error: command XPStyle not valid in Function
evidently I'm approaching this wrong and I can't interpret the error. Would be happy for any ideas on how to resolve this.
Thanks!
You cannot call !insertmacro MUI_PAGE_LICENSE dynamically, the number of pages is determined at compile time.
You can however skip pages to achieve this:
InstallDir "$Temp\Test"
!include MUI2.nsh
!include nsDialogs.nsh
!include WinMessages.nsh
!include LogicLib.nsh
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipLicensePage
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
Page Custom InfoPageCreate InfoPageValidate
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Var ShowLicensePage
Function SkipLicensePage
${IfThen} $ShowLicensePage = 0 ${|} Abort ${|} ; Skip it the first time
FunctionEnd
Function OnShowLicense
SendMessage $hWndParent ${WM_COMMAND} 3 "" ; Click the (hidden) back button
FunctionEnd
Var InstDirCtl
Function InfoPageCreate
StrCpy $ShowLicensePage 1
GetDlgItem $0 $hWndParent 3
ShowWindow $0 0 ; Hide the back button
!insertmacro MUI_HEADER_TEXT "Blah blah" "blah blah blah"
nsDialogs::Create 1018
Pop $0
${NSD_CreateText} 0 13u 100% 12u "$InstDir"
Pop $InstDirCtl
${NSD_CreateLink} 2u 40u -4u 12u "License"
Pop $0
${NSD_OnClick} $0 OnShowLicense
nsDialogs::Show
FunctionEnd
Function InfoPageValidate
${NSD_GetText} $InstDirCtl $InstDir
FunctionEnd
I'm writing an NSIS script, in this using some sections to execute EXE files. on depending output, I need to go back from the section to other custom pages but here nsis is moving to another section even though keeping of NSD_OnBack function or just calling the particular function
I have tried below 2 methods.
${NSD_OnBack} "callbackfunction"
call callbackfunction
//Section started
Section "validation" VALIDATION
DetailPrint "Executing Validation"
File "Folder_name\Validation.exe"
nsExec::Exec '"$INSTDIR\Validation.exe" $arg1 $arg2 $arg3'
IfFileExists "$INSTDIR\Output.txt" pass fail
pass:
FileOpen $chk "$INSTDIR\Output.txt" r
FileRead $chk $1
MessageBox MB_OK|MB_ICONSTOP "Validation_Output : in 1 $1"
Push $1
Push "true"
Call StrContains
Pop $3
${If} $3 == "true"
call someotherfunction
${ELSE}
goto fail
${ENDIF}
FileClose $chk
Delete $chk
fail:
MessageBox MB_OK|MB_ICONSTOP "fail"
//Here this call is not working
${NSD_OnBack} "callbackfunction"
SectionEnd
Function callbackfunction
GetDlgItem $0 $HWNDPARENT 2
${IF} $portalname == "centralised"
${IF} $username == ""
call CentralisedPage
${ENDIF}
${ELSE}
${IF} $username == ""
call SetCustom
${ENDIF}
${ENDIF}
Functionend
I am expecting to move other page based on EXE results.
${NSD_OnBack} is a callback for nsDialogs custom pages and it is invoked when the user presses the back button on that page, it is not relevant here.
Ideally you should collect all information before you get to the InstFiles page but if you can't do that then I would recommend that you just show a custom page after the InstFiles page if required.
If you absolutely need to execute sections multiple times you can use more than one InstFiles page:
!include LogicLib.nsh
!include WinMessages.nsh
!include nsDialogs.nsh
!include Sections.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init1stStage
!insertmacro MUI_PAGE_INSTFILES
Page Custom MyCustomPageCreate
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init2ndStage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Var Needs2ndStage
Section "1st stage" SID_1
DetailPrint "1st stage"
MessageBox mb_yesno "Needs 2nd stage?" IDNO nope
StrCpy $Needs2ndStage 1
nope:
SectionEnd
Section "-2nd stage" SID_2
DetailPrint "2nd stage"
SectionEnd
Function Init1stStage
!insertmacro UnselectSection ${SID_2}
FunctionEnd
Function Init2ndStage
!insertmacro UnselectSection ${SID_1}
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
FunctionEnd
Function MyCustomPageCreate
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
!insertmacro SelectSection ${SID_2}
GetDlgItem $0 $hWndParent 1
SendMessage $0 ${WM_SETTEXT} "" "STR:C&ontinue"
GetDlgItem $0 $hWndParent 3
ShowWindow $0 0 ; Hide back
GetDlgItem $0 $hWndParent 2
EnableWindow $0 0 ; Disable cancel
!insertmacro MUI_HEADER_TEXT "Blah" "Blah blah blah"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "Enter blah blah before you can enter the 2nd stage"
Pop $0
nsDialogs::Show
FunctionEnd
Is there a way to make the NSIS installer skip certain dialogs?
It has these command-line arguments,
/S, /NCRC and /D=dir
Although /S and /NCRC can used for silent and unattended modes, is there are command-line arguments to make the installer skip certain dialogs in the installer and show the rest of the dialog? For example. skip the Welcome dialog and the next two dialogs and go to the fourth one.
/S, /NCRC and /D= are the only installer parameters with built-in support, anything else you have to handle yourself.
Pages can be skipped by calling Abort in the page pre callback. It is also possible to jump forward a specific number of pages. The GetOptions macro can be used to parse the command line.
OutFile Test.exe
RequestExecutionLevel user
InstallDir $Temp
!include LogicLib.nsh
!include FileFunc.nsh
Page License LicPre
Page Components CmpPre
Page Directory "" DiShow
Page InstFiles
Var SkippedL
Var SkippedC
!macro AbortIfCmdlineParam Switch Var
${GetParameters} $0
ClearErrors
${GetOptions} $0 "${Switch}" $0
${IfNot} ${Errors}
${If} ${Var} = 0
StrCpy ${Var} 1
Abort
${EndIf}
${EndIf}
!macroend
Function LicPre
!insertmacro AbortIfCmdlineParam "/SkipL" $SkippedL
FunctionEnd
Function CmpPre
!insertmacro AbortIfCmdlineParam "/SkipC" $SkippedC
FunctionEnd
Function DiShow
# Disable back button if both pages skipped, this is optional
${If} $SkippedL <> 0
${AndIf} $SkippedC <> 0
GetDlgItem $0 $hwndparent 3
EnableWindow $0 0
${EndIf}
FunctionEnd
Section
SectionEnd
Run as Test /SkipL /SkipC to skip both.
Or:
OutFile Test.exe
RequestExecutionLevel user
InstallDir $Temp
!include LogicLib.nsh
!include FileFunc.nsh
Page License "" LicShow
Page Components
Page Directory
Page InstFiles
Function LicShow
Var /Global HasSkipped
${GetParameters} $0
ClearErrors
${GetOptions} $0 "/Skip=" $0
${IfNot} ${Errors}
${AndIf} $0 < 4 ; Don't let user skip InstFiles
${AndIf} $HasSkipped = 0
StrCpy $HasSkipped 1
SendMessage $HWNDPARENT 0x408 $0 ""
${EndIf}
FunctionEnd
Section
SectionEnd
...and run as Test /Skip=2.
I want to build a NSIS-script, which has three section
section Main
section Minor
section Shared
Shared is invisible and would be installed, if Main or Minor is checked. If I start the installer, every section (Main, Minor) is checked.
Now it should be able to define the section (in silent install). What have I to change, to only install Main or Minor or Both?
Name "Test"
Outfile "Test.exe"
;RequestExecutionLevel ?
!include "Sections.nsh"
!include "LogicLib.nsh"
!include "FileFunc.nsh" ;For GetOptions
Page Components "" "" EnforceSectionDependencies
Page InstFiles
Section /o "Main" SID_MAIN
DetailPrint Main
SectionEnd
Section /o "Minor" SID_MINOR
DetailPrint Minor
SectionEnd
Section "" SID_SHARED
DetailPrint Shared
SectionEnd
!macro CheckSectionSwitch sw sid
${GetOptions} $0 '${sw}' $9
${IfNot} ${Errors}
StrCpy $1 1
!insertmacro SelectSection ${sid}
${EndIf}
!macroend
Function .onInit
${GetParameters} $0
StrCpy $1 0 ;Any section swithes?
ClearErrors
!insertmacro CheckSectionSwitch '/Main' ${SID_MAIN}
!insertmacro CheckSectionSwitch '/Minor' ${SID_MINOR}
${If} $1 = 0
;Set defaults
!insertmacro SelectSection ${SID_MAIN}
!insertmacro SelectSection ${SID_MINOR}
${EndIf}
call EnforceSectionDependencies
FunctionEnd
Function EnforceSectionDependencies
!insertmacro UnselectSection ${SID_SHARED}
${If} ${SectionIsSelected} ${SID_MAIN}
${OrIf} ${SectionIsSelected} ${SID_MINOR}
!insertmacro SelectSection ${SID_SHARED}
${EndIf}
FunctionEnd
You should look at the Section management part of the documentation, notably the SectionSetFlags to change the sections selections.
Also, maybe that the How to control Section selections, while using SubSections & InstTypes example will be useful.