What I want to do with this script is to copy a file in a folder who already exists.
But it can be at the root (C:) or in the program files.
There what I want, but this script doesn’t work:
${If} ${FileExists} "C:\Cisco Systems\VPN Client\Profiles"
InstallDir "C:\Cisco Systems\VPN Client\Profiles"
${ElseIf} ${FileExists} "$PROGRAMFileS\Cisco Systems\VPN Client\Profiles"
InstallDir "$PROGRAMFileS\Cisco Systems\VPN Client\Profiles"
${EndIf}
Someone can help me?
Thank you
Set $instdir in .onInit with StrCpy:
!include LogicLib.nsh
InstallDir "C:\Something\something" ; Used if neither of the files exist.
Function .onInit
${If} ${FileExists} "C:\Cisco Systems\VPN Client\Profiles"
StrCpy $InstDir "C:\Cisco Systems\VPN Client\Profiles"
${ElseIf} ${FileExists} "$ProgramFiles\Cisco Systems\VPN Client\Profiles"
StrCpy $InstDir "$ProgramFiles\Cisco Systems\VPN Client\Profiles"
${EndIf}
FunctionEnd
Related
In order to create a signed uninstaller, I cannot create this using the usual NSIS WriteUninstaller command, because the usually script will create the uninstaller and embed it inside the installer, so there is no chance to sign the uninstaller. For details please see https://nsis-dev.github.io/NSIS-Forums/html/t-245688.html.
This means that I would have to create a separate uninstaller script, sign that, and then embed it in the installer using a normal File command. This works in deleting the files; however, since the uninstaller executable that is running, it cannot delete itself, and leaves the uninstaller.exe and the MyApp directory behind. Here is my uninstaller script:
!include "LogicLib.nsh"
!include "Sections.nsh"
;Include Modern UI
!include "MUI2.nsh"
!define MAJOR_VERSION "1"
!define MINOR_VERSION "2"
!define PATCH_VERSION "3"
!define BUILD_VERSION "4"
!define APP_COPYRIGHT "MyApp © MyCompany 2021"
!define COMPANY_NAME "MyCompany"
!define FLEX_LM "FlexLM"
!define FLEX_DIR "FlexSMyApp"
!define LANG_ENGLSH "English"
!define PRODUCT_NAME "MyApp"
!define PRODUCT_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${BUILD_VERSION}"
!define SETUP_NAME "MyAppSetup.exe"
BrandingText "MyCompany"
OutFile ${SETUP_NAME}
Name "${PRODUCT_NAME}"
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}\"
InstallDirRegKey HKLM "Software\$PRODUCT_NAME" ""
ShowInstDetails hide
ShowUnInstDetails hide
SetCompressor /SOLID lzma
SetCompressorDictSize 12
Var MyAppInstallDir
Var FlexLmInstallDir
;Request application privileges for Windows
RequestExecutionLevel admin
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "MyAppLicense.txt"
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesCheck
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ComponentsLeave
!insertmacro MUI_PAGE_COMPONENTS
## This is the title on the MyApp Directory page
!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_A)"
!define MUI_PAGE_HEADER_SUBTEXT "Please choose the folder in which to install MyApp."
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesA
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
## This is the title on the FlexLM Directory page
!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_B)"
!define MUI_PAGE_HEADER_SUBTEXT "Please choose the folder in which to install FlexLM."
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesB
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE DeleteSectionsINI
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
LangString NoSectionsSelected ${LANG_ENGLSH} "You haven't selected any sections!"
LangString MUI_DIRECTORYPAGE_TEXT_TOP_A ${LANG_ENGLSH} "Setup will install \
${PRODUCT_NAME} in the following folder..."
LangString MUI_DIRECTORYPAGE_TEXT_TOP_B ${LANG_ENGLSH} "Setup will install \
${FLEX_LM} in the following folder..."
;--------------------------------
; Settings
!define PROG1_InstDir "$PROGRAMFILES64\${PRODUCT_NAME}\"
!define PROG1_StartIndex ${SEC1}
!define PROG1_EndIndex ${SEC1}
!define PROG2_InstDir "C:\${FLEX_DIR}"
!define PROG2_StartIndex ${SEC3}
!define PROG2_EndIndex ${SEC3}
;--------------------------------
; Function
; StrContains
; This function does a case sensitive searches for an occurrence of a substring in a string.
; It returns the substring if it is found.
; Otherwise it returns null("").
; Written by kenglish_hi
; Adapted from StrReplace written by dandaman32
Var STR_HAYSTACK
Var STR_NEEDLE
Var STR_CONTAINS_VAR_1
Var STR_CONTAINS_VAR_2
Var STR_CONTAINS_VAR_3
Var STR_CONTAINS_VAR_4
Var STR_RETURN_VAR
Function StrContains
Exch $STR_NEEDLE
Exch 1
Exch $STR_HAYSTACK
; Uncomment to debug
;MessageBox MB_OK 'STR_NEEDLE = $STR_NEEDLE STR_HAYSTACK = $STR_HAYSTACK '
StrCpy $STR_RETURN_VAR ""
StrCpy $STR_CONTAINS_VAR_1 -1
StrLen $STR_CONTAINS_VAR_2 $STR_NEEDLE
StrLen $STR_CONTAINS_VAR_4 $STR_HAYSTACK
loop:
IntOp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_1 + 1
StrCpy $STR_CONTAINS_VAR_3 $STR_HAYSTACK $STR_CONTAINS_VAR_2 $STR_CONTAINS_VAR_1
StrCmp $STR_CONTAINS_VAR_3 $STR_NEEDLE found
StrCmp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_4 done
Goto loop
found:
StrCpy $STR_RETURN_VAR $STR_NEEDLE
Goto done
done:
Pop $STR_NEEDLE ;Prevent "invalid opcode" errors and keep the
Exch $STR_RETURN_VAR
FunctionEnd
!macro _StrContainsConstructor OUT NEEDLE HAYSTACK
Push `${HAYSTACK}`
Push `${NEEDLE}`
Call StrContains
Pop `${OUT}`
!macroend
!define StrContains '!insertmacro "_StrContainsConstructor"'
;--------------------------------
; Start sections
Section "MyApp" SEC1
;MessageBox MB_OK "SEC1 #1 INSTDIR is $INSTDIR"
${StrContains} $0 "MyApp" "$INSTDIR"
;MessageBox MB_OK "SEC1 #2 0 is $0"
StrCmp $0 "" notfoundMyApp
StrCpy $MyAppInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #3 MyAppInstallDir is $MyAppInstallDir"
Goto doneMyApp
notfoundMyApp:
;MessageBox MB_OK 'Did not find MyApp string'
doneMyApp:
${StrContains} $0 "Flex" "$INSTDIR"
StrCmp $0 "" notfoundFlex
StrCpy $FlexLmInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #4 FlexLmInstallDir is $FlexLmInstallDir"
Goto doneFlex
notfoundFlex:
;MessageBox MB_OK 'Did not find Flex string'
##All the files in Group 1 will be installed to the same location, $INSTDIR
SetOutPath "$INSTDIR"
File MyApp.exe
File ReleaseNotes.txt
File MyCompany_LandingPage_114.bmp
File MyAppLicense.txt
# create a shortcut named "new shortcut" in the start menu programs directory
CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$InstDir\${PRODUCT_NAME}.exe"
# Add application to registry
ClearErrors
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Company Name' "${COMPANY_NAME}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Version' "${PRODUCT_VERSION}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'AppID' "{A0E84732-E2B2-46E5-8CA2-462B8DF92DCD}"
# Add program to Add/Remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayIcon" "$PROGRAMFILES64\${PRODUCT_NAME}\${PRODUCT_NAME}.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"AppID" "{A0E84732-E2B2-46E5-8CA2-462B8DF92DCD}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayName" "${PRODUCT_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"Publisher" "${COMPANY_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"UninstallString" "$\"$INSTDIR\uninstaller.exe$\""
!ifndef INNER
SetOutPath $INSTDIR
; this packages the signed uninstaller
File $%TEMP%\uninstaller.exe
!endif
doneFlex:
# messagebox mb_ok sec1
SectionEnd
Section "FlexLM" SEC3
;MessageBox MB_OK "SEC3 #1 INSTDIR is $INSTDIR"
;MessageBox MB_OK "SEC1 #1 INSTDIR is $INSTDIR"
${StrContains} $0 "Pro" "$INSTDIR"
;MessageBox MB_OK "SEC1 #2 0 is $0"
StrCmp $0 "" notfoundMyApp
StrCpy $MyAppInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #3 MyAppInstallDir is $MyAppInstallDir"
Goto doneMyApp
notfoundMyApp:
;MessageBox MB_OK 'Did not find MyApp string'
${StrContains} $0 "Flex" "$INSTDIR"
StrCmp $0 "" notfoundFlex
StrCpy $FlexLmInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #4 FlexLmInstallDir is $FlexLmInstallDir"
Goto doneFlex
notfoundFlex:
;MessageBox MB_OK 'Did not find Flex string'
doneFlex:
##All the files in Group 2 will be installed to the same location, $INSTDIR
SetOutPath "$INSTDIR"
File installs.exe
File lmdown.exe
File lmflex.exe
# define uninstaller name
WriteUninstaller $INSTDIR\uninstaller.exe
doneMyApp:
# messagebox mb_ok sec3
SectionEnd
;--------------------------------
;Descriptions
;Language strings
LangString DESC_SecMyApp ${LANG_ENGLISH} "MyAppTM software is an easy-to-use suite of tools."
LangString DESC_SecFlexLM ${LANG_ENGLISH} "FlexSMyApp contains all the files necessary to implement the FlexLM license server."
;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC1} $(DESC_SecMyApp)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC3} $(DESC_SecFlexLM)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
; ...
Function .onInit
!ifdef INNER
; If INNER is defined, then we aren't supposed to do anything except write out
; the uninstaller. This is better than processing a command line option as it means
; this entire code path is not present in the final (real) installer.
SetSilent silent
WriteUninstaller "$%TEMP%\uninstaller.exe"
Quit ; just bail out quickly when running the "inner" installer
!endif
## Create $PLUGINSDIR
InitPluginsDir
SetOutPath $TEMP
File /oname=spltmp.bmp "MyCompany_LandingPage_114.bmp"
splash::show 2000 $TEMP\spltmp
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 $TEMP\spltmp.bmp
FunctionEnd
; ...
Section "Files" ; or whatever
; ...
; where you would normally put WriteUninstaller ${INSTDIR}\uninstaller.exe put instead:
;!ifndef INNER
; SetOutPath $INSTDIR
; this packages the signed uninstaller
; File $%TEMP%\uninstaller.exe
;!endif
; ...
SectionEnd
!ifdef INNER
Section "Uninstall"
; your normal uninstaller section or sections (they're not needed in the "outer"
; installer and will just cause warnings because there is no WriteUninstaller command)
# Always delete uninstaller first
Delete $INSTDIR\uninstaller.exe
# now delete installed files and registry keys for MyApp
Delete $INSTDIR\config.dat
Delete $INSTDIR\MyApp.exe
Delete $INSTDIR\ReleaseNotes.txt
Delete $INSTDIR\MyCompany_LandingPage_114.bmp
Delete $INSTDIR\MyAppLicense.txt
Delete "$SMPROGRAMS\MyApp.lnk"
DeleteRegKey HKCU "SOFTWARE\${PRODUCT_NAME}"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
DeleteRegKey /ifempty HKCU "Software\Modern UI Test"
# now delete installed files and registry keys for FlexLM
Delete $INSTDIR\installs.exe
Delete $INSTDIR\lmborrow.exe
Delete $INSTDIR\lmflex.exe
# Delete the MyApp and FlexLM directories
RMDir $INSTDIR
SectionEnd
!endif
;--------------------------------
; Please don`t modify below here unless you`re a NSIS 'wiz-kid'
## Also if no sections are selected, warn the user!
Function ComponentsLeave
Push $R0
Push $R1
Call IsPROG1Selected
Pop $R0
Call IsPROG2Selected
Pop $R1
StrCmp $R0 1 End
StrCmp $R1 1 End
Pop $R1
Pop $R0
MessageBox MB_OK|MB_ICONEXCLAMATION "$(NoSectionsSelected)"
Abort
End:
Pop $R1
Pop $R0
FunctionEnd
Function IsPROG1Selected
Push $R0
StrCpy $R0 ${PROG1_StartIndex} # Group 1 start
SectionGetFlags 0 $R0 # Get section flags
IntOp $R0 $R0 & ${SF_SELECTED}
StrCmp $R0 ${SF_SELECTED} 0 +3 # If section is selected, done
StrCpy $R0 1
Exch $R0
FunctionEnd
Function IsPROG2Selected
Push $R1
StrCpy $R1 ${PROG2_StartIndex} # Group 2 start
IntOp $R1 $R1 + 1
SectionGetFlags 1 $R1 # Get section flags
IntOp $R1 $R1 & ${SF_SELECTED}
StrCmp $R1 ${SF_SELECTED} 0 +3 # If section is selected, done
StrCpy $R1 1
Exch $R1
FunctionEnd
## Here we are selecting first sections to install
## by unselecting all the others!
Function SelectFilesA
${If} ${SectionIsSelected} ${SEC1}
;MessageBox MB_OK "SEC1 #1 INSTDIR is $INSTDIR"
${Else}
Abort
${EndIf}
# If user clicks Back now, we will know to reselect Group 2`s sections for
# Components page
StrCpy $IfBack 1
# We need to save the state of the Group 2 Sections
# for the next InstFiles page
Push $R0
Push $R1
StrCpy $R0 ${PROG2_StartIndex} # Group 2 start
; Loop:
; IntOp $R0 $R0 + 1
; SectionGetFlags $R0 $R1 # Get section flags
; WriteINIStr "$PLUGINSDIR\sections.ini" Sections $R0 $R1 # Save state
; !insertmacro UnselectSection $R0 # Then unselect it
; StrCmp $R0 ${PROG2_EndIndex} 0 Loop
# Don`t install prog 1?
Call IsPROG1Selected
Pop $R0
StrCmp $R0 1 +4
Pop $R1
Pop $R0
Abort
# Set current $INSTDIR to PROG1_InstDir define
StrCpy $INSTDIR "${PROG1_InstDir}"
Pop $R1
Pop $R0
FunctionEnd
## Here we need to unselect all Group 1 sections
## and then re-select those in Group 2 (that the user had selected on
## Components page)
Function SelectFilesB
${If} ${SectionIsSelected} ${SEC3}
;MessageBox MB_OK "SEC1 #3 INSTDIR is $INSTDIR"
${Else}
Abort
${EndIf}
Push $R0
;Push $R1
StrCpy $R0 ${PROG1_StartIndex} # Group 1 start
; Loop:
; IntOp $R0 $R0 + 1
; !insertmacro UnselectSection $R0 # Unselect it
; StrCmp $R0 ${PROG1_EndIndex} 0 Loop
; Call ResetFiles
# Don't install prog 2?
Call IsPROG2Selected
Pop $R0
StrCmp $R0 1 +4
Pop $R1
Pop $R0
Abort
# Set current $INSTDIR to PROG2_InstDir define
StrCpy $INSTDIR "${PROG2_InstDir}"
;Pop $R1
Pop $R0
FunctionEnd
Does anyone have any suggestions?
UPDATE:
Thanks #Anders, I had somehow deleted the SelectFilesCheck by mistake. Now, if I use this code:
!ifdef INNER
!echo "Inner invocation" ; just to see what's going on
OutFile "$%TEMP%\tempinstaller.exe" ; not really important where this is
SetCompress off ; for speed
!else
!echo "Outer invocation"
; Call makensis again against current file, defining INNER. This writes an installer for us which, when
; it is invoked, will just write the uninstaller to some location, and then exit.
!makensis '/DINNER "${__FILE__}"' = 0
; So now run that installer we just created as %TEMP%\tempinstaller.exe. Since it
; calls quit the return value isn't zero.
!system 'set __COMPAT_LAYER=RunAsInvoker&"$%TEMP%\tempinstaller.exe"' = 2
; That will have written an uninstaller binary for us. Now we sign it with your
; favorite code signing tool.
nsExec::ExecToStack 'cmd /c "SMyApp-SignTool.bat $%TEMP%\uninstaller.exe"'
; Good. Now we can carry on writing the real installer.
OutFile ${SETUP_NAME}
SetCompressor /SOLID lzma
!endif
Section "MyApp" SEC1
;MessageBox MB_OK "SEC1 #1 INSTDIR is $INSTDIR"
${StrContains} $0 "MyApp" "$INSTDIR"
;MessageBox MB_OK "SEC1 #2 0 is $0"
StrCmp $0 "" notfoundMyApp
StrCpy $QiProInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #3 QiProInstallDir is $QiProInstallDir"
Goto doneMyApp
notfoundMyApp:
;MessageBox MB_OK 'Did not find MyApp string'
doneMyApp:
${StrContains} $0 "Flex" "$INSTDIR"
StrCmp $0 "" notfoundFlex
StrCpy $FlexLmInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #4 FlexLmInstallDir is $FlexLmInstallDir"
Goto doneFlex
notfoundFlex:
;MessageBox MB_OK 'Did not find Flex string'
##All the files in Group 1 will be installed to the same location, $INSTDIR
SetOutPath "$INSTDIR"
# specify files to go in output path
File config.dat
File MyApp.exe
File ReleaseNotes.txt
File MyApp_LandingPage_114.bmp
File MyAppLicense.txt
# create a shortcut named "new shortcut" in the start menu programs directory
CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$InstDir\${PRODUCT_NAME}.exe"
# Add application to registry
ClearErrors
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Contact' "https://www.mycompany.com/contact"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Company Name' "${COMPANY_NAME}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'DisplayName' "${PRODUCT_NAME}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'DisplayVersion' "${PRODUCT_VERSION}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'AppID' "{K2C40732-E2B2-46E5-8CA2-464L9DF92DCD}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'HelpLink' "http://www.mycompany.com/myapp/HelpDocs/index.htm"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'URLInfoAbout' "https://www.mycompany.com/myapp"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'InstallLocation' "$MyAppInstallDir"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Publisher' "${COMPANY_NAME}"
# Add program to Add/Remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayIcon" "$PROGRAMFILES64\${PRODUCT_NAME}\${PRODUCT_NAME}.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"AppID" "{K2C40732-E2B2-46E5-8CA2-464L9DF92DCD}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayName" "${PRODUCT_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"Publisher" "${COMPANY_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"UninstallString" "$\"$INSTDIR\uninstaller.exe$\""
# Delete splash page image
Delete $INSTDIR\MyApp_LandingPage_114.bmp
!ifndef INNER
;SetOutPath $INSTDIR
; this packages the signed uninstaller
File $%TEMP%\uninstaller.exe
!endif
Then I get these errors:
!makensis: returned 0
!system: "set __COMPAT_LAYER=RunAsInvoker&"C:\Users\moorer\AppData\Local\Temp\tempinstaller.exe""
!system: returned 2
Error: Can't add entry, no section or function is open!
Error in script "C:\Project\MsiPackaging\Installer\MyAppInstaller.nsi" on line 169 -- aborting creation process
But if I try to put it in a section like this:
;--------------------------------
; Start sections
Section "MyApp" SEC1
!ifdef INNER
!echo "Inner invocation" ; just to see what's going on
OutFile "$%TEMP%\tempinstaller.exe" ; not really important where this is
SetCompress off ; for speed
!else
!echo "Outer invocation"
; Call makensis again against current file, defining INNER. This writes an installer for us which, when
; it is invoked, will just write the uninstaller to some location, and then exit.
!makensis '/DINNER "${__FILE__}"' = 0
; So now run that installer we just created as %TEMP%\tempinstaller.exe. Since it
; calls quit the return value isn't zero.
!system 'set __COMPAT_LAYER=RunAsInvoker&"$%TEMP%\tempinstaller.exe"' = 2
; That will have written an uninstaller binary for us. Now we sign it with your
; favorite code signing tool.
nsExec::ExecToStack 'cmd /c "SQI-SignTool.bat $%TEMP%\uninstaller.exe"'
; Good. Now we can carry on writing the real installer.
OutFile ${SETUP_NAME}
SetCompressor /SOLID lzma
!endif
;MessageBox MB_OK "SEC1 #1 INSTDIR is $INSTDIR"
${StrContains} $0 "MyApp" "$INSTDIR"
;MessageBox MB_OK "SEC1 #2 0 is $0"
StrCmp $0 "" notfoundQI
StrCpy $QiProInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #3 QiProInstallDir is $QiProInstallDir"
Goto doneQI
notfoundQI:
;MessageBox MB_OK 'Did not find QI string'
doneQI:
${StrContains} $0 "Flex" "$INSTDIR"
StrCmp $0 "" notfoundFlex
StrCpy $FlexLmInstallDir "$INSTDIR"
;MessageBox MB_OK "SEC1 #4 FlexLmInstallDir is $FlexLmInstallDir"
Goto doneFlex
notfoundFlex:
;MessageBox MB_OK 'Did not find Flex string'
##All the files in Group 1 will be installed to the same location, $INSTDIR
SetOutPath "$INSTDIR"
# specify files to go in output path
File config.dat
File MyApp.exe
File ReleaseNotes.txt
File MyApp_LandingPage_114.bmp
File MyAppLicense.txt
# create a shortcut named "new shortcut" in the start menu programs directory
CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$InstDir\${PRODUCT_NAME}.exe"
# Add application to registry
ClearErrors
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Contact' "https://www.mycompany.com/contact"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Company Name' "${COMPANY_NAME}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'DisplayName' "${PRODUCT_NAME}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'DisplayVersion' "${PRODUCT_VERSION}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'AppID' "{K2C40732-E2B2-46E5-8CA2-464L9DF92DCD}"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'HelpLink' "http://www.mycompany.com/myapp/HelpDocs/index.htm"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'URLInfoAbout' "https://www.mycompany.com/myapp"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'InstallLocation' "$MyAppInstallDir"
WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Publisher' "${COMPANY_NAME}"
# Add program to Add/Remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayIcon" "$PROGRAMFILES64\${PRODUCT_NAME}\${PRODUCT_NAME}.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"AppID" "{K2C40732-E2B2-46E5-8CA2-464L9DF92DCD}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayName" "${PRODUCT_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"Publisher" "${COMPANY_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"UninstallString" "$\"$INSTDIR\uninstaller.exe$\""
# Delete splash page image
Delete $INSTDIR\MyApp_LandingPage_114.bmp
!ifndef INNER
;SetOutPath $INSTDIR
; this packages the signed uninstaller
File $%TEMP%\uninstaller.exe
!endif
doneFlex:
# messagebox mb_ok sec1
SectionEnd
Then I get this error:
Error: command OutFile not valid in Section
Error in script "MyAppInstaller.nsi" on line 157 -- aborting creation process
!makensis: returned 1, aborting
Error in script "C:\Projects\MsiPackaging\Installer\MyAppInstaller.nsi" on line 165 -- aborting creation process
Do you have any suggestions? TIA.
The signing code from the Wiki does not use StrCpy at all, it must be from your StrCpy $IfBack 1 line. Maybe you forgot Var IfBack above the function.
The code from the wiki should work but here is an alternative version:
#TODO: RequestExecutionLevel
#TODO: InstallDir
!include MUI2.nsh
!macro WriteSignedUninstaller Destination
!makensis '"/DGENRATINGUNINST=$%TEMP%\Uninst.exe" "${__FILE__}" "/XOutfile `$%TEMP%\tempinstaller.exe`"' = 0 ; Create fake installer
!system 'set __COMPAT_LAYER=RunAsInvoker&"$%TEMP%\tempinstaller.exe"' = 2 ; Run fake installer to generate the uninstaller
!system 'SIGNCODE <signing options> "$%TEMP%\Uninst.exe"' = 0 ; Change this line. As a demonstration, use !system 'echo Dummy >> "$%TEMP%\Uninst.exe"'
File "/oname=${Destination}" "$%TEMP%\Uninst.exe"
!macroend
!macro DeclareLanguages
!insertmacro MUI_LANGUAGE English
!macroend
!ifndef GENRATINGUNINST
# Installer:
############
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro DeclareLanguages
Section
SetOutPath $InstDir
!insertmacro WriteSignedUninstaller "$InstDir\Uninst.exe"
; File MyApp.exe
SectionEnd
!else
# Uninstaller:
##############
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro DeclareLanguages
!verbose push 2
SilentInstall Silent
Section
WriteUninstaller "${GENRATINGUNINST}"
Quit
SectionEnd
!verbose pop
Section -Uninstall
; Delete "$InstDir\MyApp.exe"
Delete "$InstDir\Uninst.exe"
RMDir "$InstDir"
SectionEnd
!endif # EOF
Thanks for the feedback, #Anders. In the end, I found this SelfDel plugin, which allows me to go with the separate installer and uninstaller scripts while still deleting the uninstaller:
https://nsis.sourceforge.io/SelfDel_plug-in
Name `SelfDel plug-in example`
OutFile Example.exe
XPStyle on
; Administrator privileges required.
RequestExecutionLevel admin
Page InstFiles
Section
;SelfDel::Del /RMDIR
;SelfDel::Del /REBOOT
;SelfDel::Del /SHUTDOWN
SelfDel::Del
SetAutoClose true
SectionEnd
UPDATE:
When I use use SelfDel it deletes the uninstaller.exe but does not delete the original app directory even if I use SelfDel::Del /RMDIR so I ended up going with Anders answer above.
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
Hi the below program fails to delete app files if not in program files, I mean if user installs in some other location. After uninstall the registry values are deleted but not the files in the app folder. Any help would be much appreciated.
RequestExecutionLevel admin
!define MULTIUSER_EXECUTIONLEVEL Admin
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!include MultiUser.nsh
!include FileFunc.nsh
!ifndef PRODUCT_VERSION
!define PRODUCT_VERSION "0.0.0.0"
!endif
!ifndef BUILD_TARGET
!define BUILD_TARGET "Release"
!endif
!define OUT_FILE "PlaytestMateSetup.exe"
!if ${BUILD_TARGET} == "Debug"
!define PRODUCT_NAME "Playtest Mate 2.0 Debug"
!define PRODUCT_WEB_SITE "https://127.0.0.1:3000/"
!define MUI_ICON "..\PlaytestMate\Resources\Icons\IconRed.ico"
!endif
!if ${BUILD_TARGET} == "ReleaseTest"
!define PRODUCT_NAME "Playtest Mate 2.0 Staging"
!define PRODUCT_WEB_SITE "https://ca1-ptmstg01.ad.ea.com/"
!define MUI_ICON "..\PlaytestMate\Resources\Icons\IconBlue.ico"
!endif
!if ${BUILD_TARGET} == "Release"
!define PRODUCT_NAME "Playtest Mate 2.0"
!define PRODUCT_WEB_SITE "https://ca1-ptmprd01.ad.ea.com/"
!define MUI_ICON "..\PlaytestMate\Resources\Icons\IconBlack.ico"
!endif
!define PRODUCT_PUBLISHER "EA Digital Illusions CE AB"
!define RUN_REG_KEY "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
!define PRODUCT_UNINST_KEY "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_INST_KEY "SOFTWARE\${PRODUCT_NAME}"
;BUILD_DIR and CERT_PATH have to be in relation to the .nsi file
!define BUILD_DIR "..\..\Bin\${BUILD_TARGET}"
; PTM-1089
; CERT settings
!define CERT_FILE "ea_root.cer"
!define CERT_PATH "3rdparty\${CERT_FILE}"
; end PTM-1089
!include "MUI2.nsh"
; 64 bit support
!include x64.nsh
; MUI Settings
!define MUI_ABORTWARNING
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; Directory page
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE "DirectoryLeave"
; Instfiles page
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
; Finish page
Function DirectoryLeave
# Show message box then take the user back to the Directory page.
MessageBox MB_OK|MB_ICONEXCLAMATION "PTM consumes huge space because of the build sizes. We recommend to use a drive have maximum space other than C Drive"
FunctionEnd
Function createDesktopShortcut
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\PlaytestMate.exe" "-shortcut"
FunctionEnd
!define MUI_FINISHPAGE_SHOWREADME ""
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION createDesktopShortcut
; Option to run PTM after install
!define MUI_FINISHPAGE_RUN "$INSTDIR\PlaytestMate.exe"
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ModifyUnWelcome
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.LeaveUnWelcome
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_INSTFILES
; Language files
!insertmacro MUI_LANGUAGE "English"
; MUI end ------
Name "${PRODUCT_NAME}"
OutFile "${OUT_FILE}"
VIProductVersion ${PRODUCT_VERSION}
VIAddVersionKey ProductName "${PRODUCT_NAME} Installer"
VIAddVersionKey CompanyName "${PRODUCT_PUBLISHER}"
VIAddVersionKey FileDescription "Installs ${PRODUCT_NAME}"
VIAddVersionKey FileVersion ${PRODUCT_VERSION}
VIAddVersionKey ProductVersion ${PRODUCT_VERSION}
VIAddVersionKey OriginalFilename "${OUT_FILE}"
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
ShowInstDetails show
ShowUnInstDetails show
Function .onInit
!insertmacro MULTIUSER_INIT
ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
StrCmp $R0 "" done uninst
;Run the uninstaller
uninst:
ClearErrors
Exec '$R0' ; instead of the ExecWait line
done:
${If} ${RunningX64}
; disable registry redirection (enable access to 64-bit portion of registry)
SetRegView 64
; change install dir
StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"
${Else}
MessageBox MB_OK "${PRODUCT_NAME} needs 64-bit Windows"
Abort
${EndIf}
UserInfo::GetAccountType
pop $0
${If} $0 != "admin" ;Require admin rights on NT4+
MessageBox mb_iconstop "${PRODUCT_NAME} requires Administrator privileges"
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
Quit
${EndIf}
FunctionEnd
Function .onInstSuccess
RMDir /r "$LOCALAPPDATA\${PRODUCT_NAME}"
IfSilent startlauncher finished
startlauncher:
Exec '"$INSTDIR\PlaytestMate.exe"'
finished:
FunctionEnd
Section "MainSection" SEC01
Call EnsureNotRunning
Delete "$INSTDIR\*.*"
SetOutPath "$INSTDIR"
SetOverwrite try
File "${BUILD_DIR}\Builds.Core.dll"
File "${BUILD_DIR}\Builds.Core.Service.Platform.Origin.dll"
File "${BUILD_DIR}\EngineIoClientDotNet.dll"
File "${BUILD_DIR}\INIFileParser.dll"
File "${BUILD_DIR}\log4net.config"
File "${BUILD_DIR}\log4net.dll"
File "${BUILD_DIR}\log4net.xml"
File "${BUILD_DIR}\Newtonsoft.Json.dll"
File "${BUILD_DIR}\Newtonsoft.Json.xml"
File "${BUILD_DIR}\PlaytestMate.Core.dll"
File "${BUILD_DIR}\PlaytestMate.Core.dll.config"
File "${BUILD_DIR}\PlaytestMate.exe"
File "${BUILD_DIR}\PlaytestMate.exe.config"
File "${BUILD_DIR}\SocketIoClientDotNet.dll"
File "${BUILD_DIR}\WebSocket4Net.dll"
; PTM-1089
File "${CERT_PATH}"
; end PTM-1089
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\PlaytestMate.exe" "-shortcut"
CreateShortCut "$INSTDIR\Show log files.lnk" "$WINDIR\explorer.exe" "%USERPROFILE%\Documents\PlaytestMate" "$WINDIR\system32\imageres.dll" 172
; PTM-1089 you can remove this once we get a proper cert
Push "$INSTDIR\${CERT_FILE}"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "EA Root Certificate import failed: $0"
${EndIf}
; end PTM-1089
SectionEnd
Section -AdditionalIcons
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.URL" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
SectionEnd
Section -Post
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\PlaytestMate.exe"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "${PRODUCT_INST_KEY}" "InstallPath" "$INSTDIR\PlaytestMate.exe"
WriteRegStr HKLM "${PRODUCT_INST_KEY}" "Version" "${PRODUCT_VERSION}"
; estimated size
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0"
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "VersionMajor" 2
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "VersionMinor" 0
; Runs PTM on Windows start-up
WriteRegStr HKLM "${RUN_REG_KEY}" "PlaytestMate" "$INSTDIR\PlaytestMate.exe"
WriteUninstaller "$INSTDIR\uninstall.exe"
SectionEnd
!macro NOTRUNNINGMACRO un
Function ${un}EnsureNotRunning
${DisableX64FSRedirection}
SetOutPath "$INSTDIR"
File ".\killProcess.ps1"
nsExec::ExecToStack 'Powershell.exe -inputformat none -noprofile ".\killProcess.ps1"'
${EnableX64FSRedirection}
Sleep 500
performCheck:
System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "Global\{${BUILD_TARGET} }") i .R0'
IntCmp $R0 0 backupCheck isRunning isRunning
backupCheck:
System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "Global\{0}") i .R0'
IntCmp $R0 0 notRunning isRunning isRunning
isRunning:
System::Call 'kernel32::CloseHandle(i $R0)'
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT_NAME} is running. Please close it first" /SD IDCANCEL IDOK performCheck
Abort
notRunning:
FunctionEnd
!macroend
!insertmacro NOTRUNNINGMACRO ""
!insertmacro NOTRUNNINGMACRO "un."
Function un.onUninstSuccess
HideWindow
IfSilent finished
MessageBox MB_ICONINFORMATION|MB_OK "${PRODUCT_NAME} was successfully removed from your computer."
finished:
FunctionEnd
Function un.onInit
!insertmacro MULTIUSER_UNINIT
${If} ${RunningX64}
; disable registry redirection (enable access to 64-bit portion of registry)
SetRegView 64
; change install dir
StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"
${EndIf}
FunctionEnd
Var keepUserSettingsCheckbox
Var keepUserSettingsBool
Function un.ModifyUnWelcome
${NSD_CreateCheckbox} 120u -18u 50% 12u "Remove user settings"
Pop $keepUserSettingsCheckbox
SetCtlColors $keepUserSettingsCheckbox "" ${MUI_BGCOLOR}
${NSD_Check} $keepUserSettingsCheckbox ; Check it by default
FunctionEnd
Function un.LeaveUnWelcome
${NSD_GetState} $keepUserSettingsCheckbox $0
${If} $0 <> 0
StrCpy $keepUserSettingsBool "True"
${Else}
StrCpy $keepUserSettingsBool "False"
${EndIf}
FunctionEnd
Function un.GetMyDocs
ReadRegStr $0 HKCU \
"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" \
Personal
FunctionEnd
Section Uninstall
Call un.EnsureNotRunning
RMDir /r "$INSTDIR"
RMDir /r "$INSTDIR\crashDumps"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*"
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
RMDir /r "$PROGRAMFILES64\${PRODUCT_NAME}"
StrCmp $keepUserSettingsBool "True" 0 +11
Delete "$LOCALAPPDATA\${PRODUCT_NAME}\*.*"
RMDir /r "$LOCALAPPDATA\${PRODUCT_NAME}"
Call un.GetMyDocs
RMDir /r "$0\${PRODUCT_NAME}"
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_INST_KEY}"
DeleteRegValue HKLM "${RUN_REG_KEY}" "${PRODUCT_NAME}"
SetAutoClose true
SectionEnd
With just a quick glance at your document here. Maybe try using this were applicable.. Don't quote me on this; I'm tired and should get some sleep.. Lol. Good luck.
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" `"$INSTDIR\uninstall.exe"`
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString" `"$INSTDIR\uninstall.exe" /S`
I am trying to download an .exe from a URL and have it go a folder that I want it to, not the download folder. This is what I have so far in the code:
Section "file" SEC07
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
push "http://www.URL.com/file.exe"
call InternetExplorerAuto_OpenURL
SectionEnd
At this point it opens the download folder and askes if you want to run it. How do I make it so that it saves the .exe to a folder I make on the desktop??? Please Help!!
Edit: Thank you for the help guys, but it will not make a short cut for the exe in the file I tell it to. It keeps making a doc called E. Am I doing something wrong or am I missing a line of code in there. This is what I have.
Section "CleanWDF" SEC09
SetOutPath "$INSTDIR\cleanWDF.exe"
SetOverwrite ifnewer
NSISdl::download_quiet "download.File.com/File.exe";
CreateShortCut "$Desktop\NIS Edit\File.exe" "$INSTDIR\File.exe"
SectionEnd
Edit 2:
Here is the script that I am trying to get working. If you could please tell me where I am going wrong.
; Script generated by the HM NIS Edit Script Wizard.
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Support tool"
!define PRODUCT_VERSION "3.0"
!define PRODUCT_PUBLISHER "Me"
!define PRODUCT_WEB_SITE "https://www.mywebsite.com"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\AppPaths\C:\Users\sgould\Desktop\NIS Edit"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
; MUI 1.67 compatible ------
!include "MUI2.nsh"
; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!insertmacro MUI_PAGE_COMPONENTS
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_RUN "$INSTDIR\C:\Users\"user"\Desktop\NIS Edit"
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES
; Language files
!insertmacro MUI_LANGUAGE "English"
; MUI end ------
!define VARIANT_TRUE -1 ;((VARIANT_BOOL)-1)
!define VT_ERROR 10
!define DISP_E_PARAMNOTFOUND 0x80020004
!define CLSCTX_LOCAL_SERVER 0x4
!define CLSID_InternetExplorer {0002DF01-0000-0000-C000-000000000046}
!define IID_IWebBrowserApp {0002DF05-0000-0000-C000-000000000046}
!define IWebBrowserApp.Navigate ->11(i,i,i,i,i)i
!define IWebBrowserApp.put_Visible ->41(&i2)i
Function InternetExplorerAuto_OpenURL
exch $2
push $0
push $1
System::Call "ole32::CoCreateInstance( \
g '${CLSID_InternetExplorer}', i 0, \
i ${CLSCTX_LOCAL_SERVER}, \
g '${IID_IWebBrowserApp}', *i 0 r0)"
System::Call "$0${IWebBrowserApp.put_Visible} (${VARIANT_TRUE}).r1"
System::Call "*(i ${VT_ERROR},i ${DISP_E_PARAMNOTFOUND},i)i.r1" ;VARIANT
System::Call 'Oleaut32::SysAllocString(w "$2")i.r2'
System::Call "$0${IWebBrowserApp.Navigate} ($2,$1,$1,$1,$1)"
System::Free $1
System::Call 'Oleaut32::SysFreeString(ir2)'
System::Call "$0->2()"
pop $1
pop $0
pop $2
FunctionEnd
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "supportTools.exe"
InstallDir "C:\Users\"user"\Desktop\NIS Edit"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show
Section "file" SEC03
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
push "http:"
CreateShortCut "$Desktop\file.lnk" "$Desktop\NSI Edit\file.exe"
call InternetExplorerAuto_OpenURL
SectionEnd
Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\C:\Users\sgould\Desktop\NIS Edit\NIS Edit"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\SupportTools.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd
; Section descriptions
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
FunctionEnd
Function un.onInit
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2
Abort
FunctionEnd
Section Uninstall
Delete "$INSTDIR\${PRODUCT_NAME}.url"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file-2.30-bin.zip"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$INSTDIR\file.exe"
Delete "$SMPROGRAMS\Support Tools\Uninstall.lnk"
Delete "$SMPROGRAMS\Support Tools\Website.lnk"
RMDir "$INSTDIR"
RMDir ""
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
SectionEnd
I don't know what is that InternetExplorerAuto_OpenURL function you're calling. I use NSISDL:
NSISdl::download "http://www.URL.com/file.exe" "C:\temp\file.exe"
Use NSISdl Plugin
NSISdl::download "http://example.com/example.exe" "$Desktop\Your_Folder\example.exe"
There are several issues:
SetOutPath is for setting the directory wher you want to put some files, it is not the path of a single file.
the syntax for calling NSISdl::download_quiet is
NSISdl::download_quiet url_of_the_file_to_get name_of_the_local_file
in your case, something like
SetOutPath "$INSTDIR"
NSISdl::download_quiet "download.File.com/File.exe" "$INSTDIR\File.exe"
in the code you posted, you seem to have only the url part
The extension for a shortcut is .lnk and not .exe thus the call to CreateShortcut should be
CreateShortCut "$Desktop\NIS Edit\File.lnk" "$INSTDIR\File.exe"
It seems just weird to create a shortcut in a subdirectory of the desktop. Or maybe that you want to create a shortcut in the $PROGRAMFILES directory where the usage is to put it in a subdirectory ?
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.