I've made a simple installer that installs test.txt, but there are several problems:
The created folder+link in start menu isn't deleted
The uninstaller + folder isn't deleted
Does anyone know why?
#defines
outFile "Installer.exe"
installDir $DESKTOP\test
section
setOutPath $INSTDIR
writeUninstaller $INSTDIR\uninstaller.exe
createShortCut "$SMPROGRAMS\TestApplication\Uninstaller.lnk" "$INSTDIR\uninstaller.exe"
file test.txt
messageBox MB_OK "Hello World!"
sectionEnd
section "Uninstall"
delete $INSTDIR\uinstaller.exe
delete "$SMPROGRAMS\TestApplication\Uninstaller.lnk"
delete $INSTDIR\test.txt
sectionEnd
http://nsis.sourceforge.net/Shortcuts_removal_fails_on_Windows_Vista
and use RmDir "$INSTDIR" after the delete commands to delete the install folder
In addition to the answers pointing out that you never call RmDir $INSTDIR, you've also mistyped the uninstaller executable name:
delete $INSTDIR\uinstaller.exe
You've missed the 'n'.
Related
I am using special logging build to generate installation logs.
I have observed the logs are not generating when called another installer from installer script.
For ex -
ExecWait '"$INSTDIR\installer1.exe" /S _?=$INSTDIR'
The log is generating for main installer but not for installer1.exe
The installer1.exe contains lots of components and I need to print the logs for the same. I have tried enabling logset on in the installer1 script but no luck.
Tried using dumplog but it doesn't work with silent installation.
Any help would be appreciated!
Sample code from Main Installer script --
InstallDir "C:\MyFolder"
Name "${PRODUCT_NAME_VERSION}"
OutFile "${OUT_FILE}"
Section "Test"
SetOutPath $INSTDIR
LogSet on
ExecWait '"$EXEDIR\Packages\installer1.exe" /S /INST=$INSTDIR' $0
SectionEnd
Sample code from sub-installer script ---
InstallDir "C:\MyFolder"
Section "-Demo"
SetOutPath $INSTDIR
LogSet on
LogText "Print something"
SetOutPath $INSTDIR\ExternalFolder\Demo
File /nonfatal /a /r $INSTDIR\ExternalFolder\Demo\Test
ExecWait '"$INSTDIR\ExternalFolder\Demo\Test\TestSetup.exe" /silent '
SectionEnd
The sub-installer (installer1.exe) is pre-compiled and kept the exe in $EXEDIR\Packages\installer1.exe The patch is valid.
_?= is special syntax that is only supported by NSIS uninstallers, installers use /D=.
ExecWait '"$InstDir\installer.exe" /S /D=$InstDir'
Logging of course has to be enabled in this sub-installer as well.
/D= overrides the InstallDir attributes, forcing $InstDir to the specified path before .onInit is executed.
InstallDir $INSTDIR does not make sense, use something like InstallDir "$ProgramFiles\MyApp"
this is the first time I work with NSIS, I want to edit an script NSIS to allow me:
If first instalation -> create the directory "Affaires" in the location "C:\Users\ali.ait-mouhoub.ext\AppData".
If it is an update (So the directory "Affaires" it already exists in "C:\N.O.E") -> move the directory "Affaires" with its contents to "C:\Users\ali.ait-mouhoub.ext\AppData".
The current script creates the directory "Affaires" in "C:\N.O.E".
Can you please help me modify my script to meet my needs?
If the both the new and old locations are on the same volume then you can use Rename:
Section
Rename "$InstDir\Stuff" "$InstDir\OldStuff"
SectionEnd
If the new location might be on a different volume then you have to copy+delete:
!include LogicLib.nsh
Section
ClearErrors
CopyFiles /Silent "$InstDir\Stuff" "x:\Backup"
${If} ${Errors}
MessageBox MB_ICONSTOP "Unable to move!"
${Else}
RMDir /R "$InstDir\Stuff"
${EndIf}
SectionEnd
In nsi script with MUI2.nsh
Code:-
!macro SECTION_BEGIN
Section ""
Call zip2exe.SetOutPath
!macroend
!macro SECTION_END
SectionEnd
!macroend
But If I want to define two or more section then in that case how to incorporate SECTION_BEGIN part?
Section "Main Component" MainCom
#SectionIn RO # Just means if in component mode this is locked
Call zip2exe.SetOutPath
;Store installation folder in registry
WriteRegStr HKLM "Software\${ZIP2EXE_NAME}" "" $INSTDIR
;Registry information for add/remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ZIP2EXE_NAME}" "DisplayName" "${ZIP2EXE_NAME}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ZIP2EXE_NAME}" "NoRepair" 1
;Create optional start menu shortcut for uninstaller and Main component
;Create uninstaller
WriteUninstaller "${ZIP2EXE_NAME}_uninstaller.exe"
#!macroend
#!macro SECTION_END
SectionEnd
#!macroend
;--------------------------------
;Uninstaller Section
Section "Uninstall"
;Delete the appdata directory + files
RMDir /r "${INSTDIR_DATA}\*.*"
RMDir "${INSTDIR_DATA}"
;Delete Start Menu Shortcuts
Delete "$SMPROGRAMS\${ZIP2EXE_NAME}\*.*"
RmDir "$SMPROGRAMS\${ZIP2EXE_NAME}"
SectionEnd
#!macro SECTION_END
If we omit SECTION_BEGIN part then error comes. If we mention SECTION_BEGIN in both sections then also error comes.
What will be the solution to this problem?
If actually want to use Zip2Exe then you can modify parts of NSIS\Contrib\zip2exe\Base.nsh from
!macro SECTION_END
SectionEnd
!macroend
to something like this
!macro SECTION_END
SectionEnd
!if /FileExists "c:\mycustomzip2exefiles\mycustomsections.nsh"
!include "c:\mycustomzip2exefiles\mycustomsections.nsh"
!endif
!macroend
You can then put whatever code you want in c:\mycustomzip2exefiles\mycustomsections.nsh:
Section "My other section"
SetOutPath $InstDir
File "anotherfile.txt"
SectionEnd
However, Zip2Exe is mainly something you use to create simple self-extracting executables, you should not use it to create full installers.
When you create a real installer you don't use Zip2Exe, you use MakeNSIS and there is no such thing as a SECTION_BEGIN macro, you just add as many sections as you want to your .NSI file.
Example2.nsi contains a basic installer/uninstaller.
When uninstaling the software to do the complete cleanup calling the function in the C++ DLL .
To achieve this I am placing the DLL file in the temp directory. Then in the Uninstall section calling the DLL function. But it is not calling the function.
If I place that DLL file in the installed directory then it is calling the DLL function.
But I should not place it in the installed directory because I am calling this function when uninstalling.
Is it the correct way that I am doing? or is there any other way?
Below is my code snippet:
Section "MyApp"
InitPluginsDir
SetOutPath $PluginsDir
File "C:\Desktop\KillNofificationSoftly.dll"
SetOutPath $Temp
MessageBox MB_OK "Temp Path $Temp"
System::Call 'KERNEL32::AddDllDirectory(w "$PluginsDir")'
SetOutPath $INSTDIR
SectionEnd
Section "Uninstall"
System::Call "$PluginsDir\KillNofificationSoftly.dll::KillMeSoftly() i.r0 ?e"
Pop $1 ; LastError
${If} $0 = 0
MessageBox MB_OK "Success"
${EndIf}
SectionEnd
You are extracting the .DLL in the installer! $PluginsDir is deleted when the installer finishes. Move all the code to the uninstaller section.
If you are the author of this .DLL you should consider writing a NSIS plug-in, then it becomes just a single line of code, no need for System::Call.
My installation EXE should unzip itself in a temp folder, then execute an app therein (with passing args), return and delete the temp folder again.
How do I write the nsi script?
It sounds to me like you are trying to create a portable application. Portable applications are always better when the original author adds support for it because it can handle registry and other configuration files correctly.
If you still want to create a launcher application you can do something like this:
OutFile "MyLauncher.exe"
RequestExecutionLevel User
SilentInstall Silent
SetCompressor LZMA
!include FileFunc.nsh
!insertmacro GetParameters
Section
${GetParameters} $1
InitPluginsDir
SetOutPath $PluginsDir
File "c:\myfiles\MyApp.exe"
File /r "c:\myfiles\otherfiles\*.*" ; If you need to include other files required by the application
ExecWait '"$PluginsDir\MyApp.exe" /param1 "pa ra m2" /param3 $1' $0 ; $1 contains the parameters passed to your launcher, remove it if you don't want to pass those arguments
SetErrorLevel $0
SetOutPath $Temp ; Don't lock $PluginsDir so it can be deleted automatically by the installer
SectionEnd
Answering my own question.
The required nsi script skeleton should look like this:
# The name of the installer (arbitrary)
Name "hello"
# The name of the installation file
OutFile "hello.exe"
# where put the installation - other options would be $TEMP, etc.
InstallDir $DESKTOP
RequestExecutionLevel user # no Windows UAC popup please!
SilentInstall silent # completely silent install
SetCompressor /SOLID /FINAL lzma # max compression for inst. file
# The stuff to install
Section ""
SetOutPath $INSTDIR # where to install (overwritable by user!)
File /r D:\...\... # where the install material lives
SectionEnd
# this function auto-runs after installation is fine
Function .onInstSuccess
# parameter are passed through via $CMDLINE
ExecWait '"$OUTDIR\hello.dist\hello.exe" $CMDLINE'
RMDir /r "$OUTDIR\hello.dist" # remove install folder again
FunctionEnd