How do I use/include StrContains in NSIS - 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}

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

I wanted to know how to call a function from C++ executable using NSIS

I wanted to know how to call a function from C++ executable using NSIS.
I am using the below method but it is not calling the function.
!include LogicLib.nsh
Section
SetOutPath $INSTDIR
File E:\TestNullSoft\Test1.exe
File E:\TestNullSoft\Test2.dll
System::Call 'KERNEL32::AddDllDirectory(w "$INSTDIR")'
Pop $1 ;
${If} $0 = 0
MessageBox MB_OK "Function is NOT CALLED" IDOK
${EndIf}
SectionEnd
AddDllDirectory function is declared in the C++ project like as shown below:
You cannot call functions in .EXE files, only .DLL files.
Specifically, System::Call will call LoadLibrary and GetProcAddress and LoadLibrary cannot load a .EXE.

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: Access values of combo box of custom page?

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.

NSIS script condition compilation based upon existence of a file

I have an NSIS based installer that I need to be able generate slightly different versions of under different conditions.
The conditions are easy to establish at compile time, if a particular file exists on the disk then the alternative branding can be used. I know I could use a command-line option to the makensis.exe to provide this behaviour, but it would be better if the compiler could take care of this for me.
Is there a way of making a compile time "IfExist" type logic?
!macro CompileTimeIfFileExist path define
!tempfile tmpinc
!system 'IF EXIST "${path}" echo !define ${define} > "${tmpinc}"'
!include "${tmpinc}"
!delfile "${tmpinc}"
!undef tmpinc
!macroend
Section
!insertmacro CompileTimeIfFileExist "$%windir%\explorer.exe" itsThere
!ifdef itsThere
MessageBox mb_Topmost yes
!else
MessageBox mb_Topmost no
!endif
SectionEnd
Note: the !system command used here assumes you are compiling on windows
I don't have the answer to your generic question of compile-time file detection, but I do have a solution to what it sounds like you're trying to accomplish.
My installers use something like this:
In the file CustomBranding.nsh:
!define CUSTOM_BRANDING
!define APPNAME "Brand X"
!define LOGO "C:\Brand_X_Logo.png"
In the main installer script:
!include /NONFATAL "CustomBranding.nsh"
!ifndef CUSTOM_BRANDING
!define APPNAME "Generic"
!define LOGO "C:\Generic_Logo.png"
!endif
Is that the kind of "alternative branding" you're asking about?

Resources