How to bundle exe file inside another exe file using nsis script - windows

I have a installer file called sample.exe. This exe file will have some components that use have to be defined such as port number, installation directory and etc. I have to bundle this sample.exe file inside another installer called test.exe. So when i try to install the test.exe, it should also install the sample.exe. i could see there are options to achieve this in nsis, but how to provide options for the use to enter the port, directory path of sample.exe while installing the test.exe ? i am beginner to nsis and any reference are example script will help me lot. Thanks in advance.

You need to create custom (installer) page where these values are entered.
Use nsDialogs for this (recommended): http://nsis.sourceforge.net/Docs/nsDialogs/Readme.html
There is no exact solution for this as your specification is really vague, rather check the examples and use provided code snippets from them.

You generally use the directory page to let the user choose the installation directory. Non-standard user input can be recorded on a custom page using the nsDialogs plug-in:
Name "Foo"
OutFile "TestSetup.exe"
RequestExecutionLevel admin
InstallDir "$ProgramFiles\Test"
!define DEFAULTPORT 666
!include nsDialogs.nsh
Var MyPort
Var PortEdit
Function .onInit
StrCpy $MyPort "${DEFAULTPORT}"
FunctionEnd
Page Directory
Page Custom MyPageCreate MyPageLeave
Page InstFiles
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0u 10% 20u 12u "Port: "
Pop $0
${NSD_CreateNumber} 20u 10% 40u 12u "$MyPort"
Pop $PortEdit
nsDialogs::Show
FunctionEnd
Function MyPageLeave
${NSD_GetText} $PortEdit $MyPort
FunctionEnd
Section
SetOutPath $InstDir
File "Sample.exe"
; Write the chosen port to a config file:
WriteIniStr "$InstDir\Config.ini" "Network" "Port" "$MyPort"
SectionEnd

Related

How to set the ALL USER Directory as an output directory for a installer created with NSIS

I am trying to install a file to ALL USER DOCUMENTS Directory(windows 7) using NSIS.
In my code i am setting "SetShellVarContext all" but still the files are getting installed at current user directory
Please help
Here is my code
# define installer name
OutFile "installer.exe"
# set desktop as install directory
InstallDir $DOCUMENTS
# default section start
Section
# define output path
SetShellVarContext all
SetOutPath $INSTDIR
# specify file to go in output path
File test.txt
# define uninstaller name
WriteUninstaller $INSTDIR\uninstaller.exe
#-------
# default section end
SectionEnd
# create a section to define what the uninstaller does.
# the section will always be named "Uninstall"
Section "Uninstall"
# Always delete uninstaller first
Delete $INSTDIR\uninstaller.exe
# now delete installed file
Delete $INSTDIR\test.txt
SectionEnd
SetShellVarContext does not affect the InstallDir attribute, you must manually set $InstDir:
Function .onInit
SetShellVarContext all
StrCpy $InstDir $Documents
FunctionEnd

Obtain Current Users %APPDATA% Path and not Admins

I am looking to get the path to the current users %APPDATA% folder.
Note: I am aware of the variable $APPDATA BUT if you run your installer with RequestExecutionLevel admin then $APPDATA will point to the admins roaming folder and NOT the current user's app data folder.
I need to find out the current users %APPDATA% path so I can write files to their roaming directory. Does anyone know how I can find this out?
RequestExecutionLevel admin
Section "Main"
MessageBox MB_OK "AppData is: $APPDATA" # knowtice that its the path to the admins folder not the current user's
SectionEnd
The term "Current User" is ambiguous, do you mean:
The user you get from WTSQueryUserToken()? (WinLogon)
The user that the shell's taskbar is running as? (GetShellWindow())
The user (parent process) that started your setup process?
All of those can be different users if you are having fun with runas!
The comment from Harry Johnston is spot on and once you start mixing %ProgramFiles% and %AppData% and/or HKLM and HKCU your setup is broken in multi-user scenarios. What happens when a different user starts the application? They are not going to have your files in their %AppData%.
If the addin is installed/registered in a global location you can install the AppData "template" files in %ProgramFiles%, %CommonProgramFiles% or %ALLUSERSPROFILE% and when your addin runs as a specific user for the first time you copy the files to %AppData%.
Active Setup could be used as a alternative but it will probably require a log-off/log-on cycle.
If you cannot implement the delayed copy/install for some reason you are left with hacks like the UAC plugin which gives you some access to the user that started your installer...
Ok, thanks for the advice but I found a nice plugin that tells me the location of all User directories. I still cant figure out which user is currently logged in but I can figure out all non-admin users which is very useful.
!include "NTProfiles.nsi"
!macro HandleUserProfiles
!define NTProfilePaths::IgnoreLocal
!ifndef __UNINSTALL__
${EnumProfilePaths} HandleUserProfile
!else
${EnumProfilePaths} un.HandleUserProfile
!endif
!macroend
!macro HandleUserProfile prefix
Function ${prefix}HandleUserProfile
Pop $R9
!ifndef __UNINSTALL__
# Copy files to user dir
SetOutPath "$R9\AppData\Roaming\Autodesk\Revit\Addins\2013" # $APPDATA = C:\ProgramData
FILE /r "${INSTALLFILEDIR}\Addins\Revit_2013\myAddin.addin"
!else
Delete "$R9\AppData\Roaming\Autodesk\Revit\Addins\2013\myAddin.addin"
!endif
# Continue Enumeration
Continue:
Push ""
Return
# Stop Enumeration
Stop:
Push "~" # Any value other than an empty string will abort the enumeration
FunctionEnd
!macroend
!insertmacro HandleUserProfile ""
!insertmacro HandleUserProfile "un."

NSIS weird behavior with GetParameters

I'm having a weird error with NSIS:
!include "MUI2.nsh"
!include "FileFunc.nsh" # To use GetParameters
Name nsDialogs
OutFile nsDialogs.exe
Function .onInit
${GetParameters} $R0
MessageBox MB_OK "$R0"
FunctionEnd
!insertmacro MUI_PAGE_WELCOME
Section
DetailPrint "hello world"
SectionEnd
If I use this command line
nsDialogs.exe /d=hello
the message box says: "/d=hello" as expected, but if I use
nsDialogs.exe /D=hello
the message box says "" and this is wrong.
Why is this happening?
From the documentation:
/D sets the default installation directory ($INSTDIR), overriding
InstallDir and InstallDirRegKey. It must be the last parameter used in
the command line and must not contain any quotes, even if the path
contains spaces. Only absolute paths are supported.
This means you cannot use /D with ${GetParameters} (/S and /NCRC are also switches used by NSIS). NSIS by design uses everything after /D= as $instdir.
The only way to detect /D is to not use InstallDir[RegKey] in your script and check if $instdir is != "" in .onInit
/D is command line parameter that let define the installation directory directly from the installer command line invocation.
See the Installer usage / Common Options chapter for details.
I don't know for sure, but I assume that NSIS strips out its inbuilt parameters by default. In that case you could try something like this:
!define myInstDir "$PROGRAMFILES\myApp"
Function .onInit
${GetParameters} $R0
StrCpy $R0 ${myInstDir} +2
MessageBox MB_OK "$$INSTDIR was changed on runtime"
FunctionEnd

Writting Folder causes error code 80

My NSIS installer is giving a error code of 80 when I attempt to copy/overwrite a folder. I think it may have to do with the fact that the folder I am attempting to copy to the users HD already exists. But in my case I will always want to overwrite it.
What does the error code 80 mean?
Heres my code:
# Write plugins to EXDS_Customisation\EXDS_USER\
ClearErrors
SetOverwrite try
SetOutPath "$INSTDIR\EXDS_User\"
FILE /r "${localInstallDir}\EXDS_Customisation\EXDS_User\${MAINPLUGINSDIR}"
${If} ${Errors}
System::Call "Kernel32::GetLastError() i() .r1"
# Prints: "Error code: 80"
MessageBox MB_ICONINFORMATION|MB_OK "Error code: $1 "
Quit
${EndIf}
If you always want to overwrite, why are you using Try and not SetOverwrite On?
Using System::Call "Kernel32::GetLastError()... is never valid. System::Call has a special ?e option but it is not useful in your case. You cannot get specific error information from NSIS, all you have is just the error flag...

Simple Input Dialog in NSIS

In my NSIS installer, I want to display an input dialog (text + textbox) to the user and to retrieve the result of that input, so that I can use it later in the NSIS script.
I've found this reference page:
http://nsis.sourceforge.net/Docs/Chapter4.html#4.9.4.15
But I couldn't find any reference to a textbox.
If it helps, what I need is the NSIS equivalent of the following AppleScript code:
display dialog "Insert value:" default answer ""
set value to text returned of result
Use nsDialogs or InstallOptions (both part of NSIS) to create a custom page:
Outfile test.exe
Requestexecutionlevel user
!include nsDialogs.nsh
Page Custom mypagecreate mypageleave
Page Instfiles
Function mypagecreate
Var /Global MyTextbox
nsDialogs::Create /NOUNLOAD 1018
Pop $0
${NSD_CreateText} 10% 20u 80% 12u "Hello World"
Pop $MyTextbox
nsDialogs::Show
FunctionEnd
Function mypageleave
${NSD_GetText} $MyTextbox $0
MessageBox mb_ok $0
Abort ;Don't move to next page (If the input was invalid etc)
FunctionEnd
Section
SectionEnd
Popup dialogs are not really supported but it can be done with this plugin...

Resources