NSIS: Access values of combo box of custom page? - nsis

I have added custom page to NSIS installer using ini files, here is a code
.
.
.
; Welcome page
!insertmacro MUI_PAGE_WELCOME
Page custom customPage "" ": custom page"
.
.
.
Function customPage
GetTempFileName $R0
File /oname=$R0 customPage.ini
InstallOptions::dialog $R0
Pop $R1
StrCmp $R1 "cancel" done
StrCmp $R1 "back" done
StrCmp $R1 "success" done
error: MessageBox MB_OK|MB_ICONSTOP "InstallOptions error:$\r$\n$R1"
done:
FunctionEnd
.
.
.
Here is a customPage.ini file
; Ini file generated by the HM NIS Edit IO designer.
[Settings]
NumFields=2
[Field 1]
Type=Label
Text=Select Version:
Left=4
Right=53
Top=16
Bottom=26
[Field 2]
Type=Combobox
Text=Combobox
ListItems=
Left=53
Right=138
Top=14
Bottom=107
I want to set values of combobox dynamically using NSIS script, how can I access combobox in nsis?

I don't have code handy but basically what you do is write ini values to that ini file, just after you extract it, but before you run InstallOptions:dialog
!insertmacro INSTALLOPTIONS_WRITE "customPage.ini" "Field 2" "State" "Blah|Value2|Foo|Bar"
See: http://nsis.sourceforge.net/Docs/InstallOptions/Readme.html
Note that in your code you aren't using the InstallOptions macros like you see in the linked webpage. Instead you are doing everything manually. Normally the InstallOptions macros extract the custom page ini files to the plugins directory. This means my code snippet might not work since you aren't following the usual pattern. So instead if the above doesn't work, try using WriteINI instead. But the concept is the same, write the value to the ini file just after extracting it, but before displaying it.

Related

Space required on MUI_PAGE_DIRECTORY is 0.0KB

I'm writing an installer for Windows application. I'm using MUI for NSIS. One of the pages of the installer is Directory Page, where I have the "Space required" field. The problem is that the space required is always 0.0KB.
I was looking for some answers, but all I found was that space is calculated automatically. I wonder if there is some way to check which folder size this macro gets? Or any other ideas?
;Pages
; Installation
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "#CPACK_RESOURCE_FILE_LICENSE#"
!insertmacro MUI_PAGE_DIRECTORY
Page custom pgAppLanguageCreate
The size is automatically calculated by the File instructions in Sections plus any extra you add with AddSize.
If you are not happy with this calculation you can force a specific size in .onInit with SectionSetSize.
I found what causes the problem.
In the "Installer Section" I used a function that copies all files.
Instead of calling it here, I just paste the entire function and now that works. It looks like you cant use "File" instruction in function because it doesn't add size to the required space this way.
If you use it in section, it works perfectly.
; Installer Sections
Section "install" Install
${If} $instState != "1"
Call deleteAllFiles
Call deleteInfoFromRegistry
Call deleteShortcut
${EndIf}
SetOutPath "$INSTDIR"
; copy files
File ${ICON}
File "slicer_license"
File /r "${INSTALL_FILE}\package\"
;File "README.txt" ;Readme file.
Call createShortcut
Call addInfoToRegistry
Call setAppLanguageShortcut
Call createLanguageFile
SectionEnd

Load the content of the embedded file into RichEdit control on the custom license page

Requirements / use case:
I have a requirement to implement custom license page in NSIS. The page should look like this: .
On the page I have RichEdit control which has to display the content of a eula.rtf file. This file is available at the compile time and I cannot distribute it separately from the installer, so it has to be somehow embedded into it.
Currently I am using NSIS 2.46 and MUI2. Here is how I create RichEdit control:
nsDialogs::CreateControl /NOUNLOAD "RichEdit20A" ${WS_VISIBLE}|${WS_CHILD}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN} ${WS_EX_STATICEDGE} 1.32u 56.62u 295.54u 63.38u ""
Pop $hCtl_test_rtLicense
Problem description:
I know that the default MUI2 license page makes use of LicenseData and/or LicenseLangString. As far as I know, in this case the .rtf file is embedded into the installer. Unfortunately I cannot figure out how to load the content from the embedded .rtf file into my RichEdit control, even though I looked through the License.nsh coming with NUI2 and through the NSIS source code as well.
And unfortunately the plugins and scripts I found (LoadRtf plugin, NsRichEdit plugin, this script and one or two more) can only load .rtf file into the RichEdit control at runtime.
Question:
How to load the content from the embedded .rtf file into the RichEdit on the custom page?
If it is not possible, is there any other way to implement my requirement?
The only thing I could think of is wrapping my current installer into another thin NSIS installer which would silently deploy the .rtf file alongside with the current installer. This feels very messy, so I would rather not do that..
The only way to do this is at run-time. To use one of the solutions you linked to you would just extract the .rtf file and call the plugin:
InitPluginsDir ; Initialize $PluginsDir, it is deleted automatically when installer quits
File "/oname=$PluginsDir\lic.rtf" "MyLicense.rtf"
# Call plugin here passing in "$PluginsDir\lic.rtf" as the file to load
Or if you don't want to use 3rd-party plugins:
Page Custom MyPage
Page InstFiles
!include LogicLib.nsh
!include nsDialogs.nsh
!define SF_RTF 2
!define EM_STREAMIN 1097
Function LoadRichRtf
System::Store S
Pop $0 ; hwnd
Pop $1 ; path to rtf
FileOpen $1 $1 r
System::Get "(i, i .R0, i .R1, i .R2)iss"
Pop $2
System::Call "*(*i 0, i 0, k r2)i.r3"
System::Call "USER32::SendMessage(ir0, i${EM_STREAMIN}, i${SF_RTF}, ir3)i.s"
loop:
Pop $0
StrCmp $0 "callback1" 0 done
System::Call 'KERNEL32::ReadFile(ir1, iR0, iR1, iR2, i0)'
Push 0 # callback's return value
System::Call "$2"
Goto loop
done:
System::Free $2
System::Free $3
FileClose $1
System::Store L
FunctionEnd
Var hCtl_test_rtLicense
Function MyPage
nsDialogs::Create 1018
Pop $0
nsDialogs::CreateControl /NOUNLOAD "RichEdit20A" ${WS_VISIBLE}|${WS_CHILD}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN} ${WS_EX_STATICEDGE} 1.32u 56.62u 295.54u 63.38u ""
Pop $hCtl_test_rtLicense
File "/oname=$PluginsDir\lic.rtf" "c:\some\local\path\License_en_US.rtf"
Push "$PluginsDir\lic.rtf"
Push $hCtl_test_rtLicense
Call LoadRichRtf
nsDialogs::Show
FunctionEnd

NSIS - Radio button to select one of many programs to install

I have 4 programs that I'd like to package into one installer and allow the user to select which one they would like to install.
I've never used NSIS before but I was recommended to give it a shot, however, I've no idea where to begin with this.
Basically I just need one page that asks the user to select a radio button then click next to install one of the following programs:
-- Install components --------------------
Select a program from the list below and
click Next to continue.
O Program 1
O Program 2
O Program 3
O Program 4
-------------------------------------------
Cancel Next
Then depending on what they choose it launches program1_setup.exe or program2_setup.exe etc.
As each of my 4 programs are installers in their own right, I take it I don't need to set up the uninstall script in NSIS as that's taken care of already?
Thanks,
Greg.
This code is similar to the one-section.nsi example.
...
!include sections.nsh
Page components
Page instfiles
Section /o "Program 1" P1
File "/oname=$pluginsdir\Setup.exe" "myfiles\Setup1.exe"
SectionEnd
Section "Program 2" P2
File "/oname=$pluginsdir\Setup.exe" "myfiles\Setup2.exe"
SectionEnd
Section ; Hidden section that runs the show
DetailPrint "Installing selected application..."
SetDetailsPrint none
ExecWait '"$pluginsdir\Setup.exe"'
SetDetailsPrint lastused
SectionEnd
Function .onInit
Initpluginsdir ; Make sure $pluginsdir exists
StrCpy $1 ${P2} ;The default
FunctionEnd
Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${P1}
!insertmacro RadioButton ${P2}
!insertmacro EndRadioButtons
FunctionEnd
You can use the CheckBitmap attribute to change the checkbox icons if you want...

How do I use/include StrContains in NSIS

Do I need to include a specific .nsh library or function definition to use the function 'StrContains' in NSIS?
I have looked for a download for the library but I cant seem to find it?
When I go to compile this code I get the compile error: "Invalid command: ${StrContains}"
!include "LogicLib.nsh"
# Compile error below
!macro test
${StrContains} $0 $1 "abc"
!macroend
Section
DetailPrint ""
SectionEnd
You need to add the function definition shown in the StrContains function page of the NSIS wiki (in the category of strings functions) in your code.
Don't forget the last statement !define StrContains ... to be able to call it with ${StrContains}

How to hide all windows until I need them in NSIS

I have a NSIS installer I want to be totally silent unless it needs to download additional files. I can make it totally silent with SilentInstall, but then i can't make my download dialog appear (i'm using InetLoad::load).
I would like to tell NSIS not to show any windows until I say so. The best I can come up with is HideWindow. Unfortantly it looks like NSIS defaults to showing the window and then hiding it causing a flicker.
How can I prevent a flickering window?
Example code:
Name "Flicker test"
OutFile "flickertest.exe"
AutoCloseWindow true
Section
HideWindow
SectionEnd
This is a hack way of doing it:
!include "${NSISDIR}\Examples\System\System.nsh"
Name "No Flicker test"
OutFile "noflickertest.exe"
AutoCloseWindow true
Function .onGUIInit
; move window off screen
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, -10000, -10000, 0, 0, ${SWP_NOOWNERZORDER}|${SWP_NOSIZE})"
FunctionEnd
Section -main
HideWindow
SectionEnd
You can use skipping pages Example for MUI2 (hide directory page if mode is update):
!define MUI_PAGE_CUSTOMFUNCTION_PRE dirPre
!insertmacro MUI_PAGE_DIRECTORY
Function dirPre
StrCmp $Mode "update" +1 +2
abort
FunctionEnd
OutFile "example.exe"
SilentInstall silent
RequestExecutionLevel user<br>
ReserveFile test.exe
Section ""<br>
 InitPluginsDir<br>
 File /oname=$PLUGINSDIR\test.exe test.exe<br>
 ExecWait "$PLUGINSDIR\test.exe"<br>
SectionEnd

Resources