I created an NSIS installer where the name of the app is taken from an .INI file (it has to be so since it will be used for multiple apps).
Name $APP_NAME
....
Function .onInit
ReadINIStr $R3 ${TECHPUB_INI_FILE} "General" "Installer_name"
StrCpy $APP_NAME $R3
....
FunctionEnd
....
Section install
....
WriteUninstaller $INSTDIR\Uninstall.exe
....
SectionEnd
The app name is correctly shown on the installer and it's the one from the .INI file. When I uninstall the app, the name is missing.
http://i48.tinypic.com/1934w9.png
Everything else works (uninstall removes all it has to remove). Any idea how to fix this?
Thank you!
The init function of the uninstaller is a separate un.onInit function. See Uninstall Callbacks.
Related
In order to sign both the installer and uninstaller, I have created a separate uninstaller script as suggested here: https://nsis-dev.github.io/NSIS-Forums/html/t-245688.html. Thus, the uninstaller script not using the WriteUninstaller way to create the uninstaller.
Please note that I am using the SelfDel plug-in to delete the uninstaller, which works successfully; however, it does not actually delete the application install directory even though I am using the /RMDIR option:
Function .onInstSuccess
;SelfDel::Del /REBOOT
;SelfDel::Del /SHUTDOWN
SelfDel::Del /RMDIR
SelfDel::Del
SetAutoClose true
FunctionEnd
Here is the full script for your reference.
!define APP_COPYRIGHT "MyApp © MyCompany 2021"
!define COMPANY_NAME "MyCompany"
!define LANG_ENGLSH "English"
!define PRODUCT_NAME "MyApp"
!define PRODUCT_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${BUILD_VERSION}"
!define SETUP_NAME "uninstaller.exe"
# define the name of the installer
OutFile ${SETUP_NAME}
Icon "favicon.ico"
!define MUI_ICON "favicon.ico"
# define the directory to install to
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}\"
# default section
Section
# define the output path for this file
SetOutPath $INSTDIR
# now delete installed files and registry keys for MyApp
ReadRegStr $0 HKCU "SOFTWARE\${PRODUCT_NAME}" "InstallLocation"
DeleteRegKey HKCU "SOFTWARE\${PRODUCT_NAME}"
Delete $0\config.dat
Delete $0\MyApp.exe
Delete $0\ReleaseNotes.txt
Delete $0\MyApp_LandingPage_114.bmp
Delete $0\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"
SectionEnd
Function .onInstSuccess
;SelfDel::Del /REBOOT
;SelfDel::Del /SHUTDOWN
SelfDel::Del /RMDIR
SelfDel::Del
SetAutoClose true
FunctionEnd
Does anyone have any suggestions on how to get it to delete the app directory? TIA.
So I don't really know the SelfDel nsis plugin that well, but have you tried just restarting your machine after deleting your install-directory like so?
SelfDel::Del /RMDIR
SelfDel::Del
SelfDel::Del /REBOOT
;or just
Reboot
That might help.
Wish you all the best.
Update
Ok so you tried to Reboot.
I researched a little further on the topic and found the same problem, but without the SelfDel plugin: How to solve "The directory is not empty" error when running rmdir command in a batch script?
But maybe you could also try to remove the directory and all the files in the "normal NSIS way" like this:
RMDir /r $YOURDIR
Try this maybe it will work, and perhaps it's just some bug from the plugin.
The SourceForge site of the plugin says it's only testet on Windows 8, so if you are using it on Windows 10 there might be some bugs.
Read the note at the bottom of the SourceForge site: https://nsis.sourceforge.io/SelfDel_plug-in
They say that it is a Trojan Virus and I would recommend to stop using it.
I would seriously consider using another plugin that is testet for Windows 10.
Wish you all the best.
I have an application which has development, testing and live versions. I have a command procedure which currently creates 3 different versions of the installer, which can be installed on 3 separate computers.
What I would like to do would be to have one NSIS script which I pass in a parameter to, which will create one of the versions of the installer changing the name of the product and the installation folder. This will allow me to install all 3 versions on the same computer.
What I have tried so far is;
Function .onInit
Var /GLOBAL INSTALL_TYPE
${GetOptions} $CMDLINE "/t" $INSTALL_TYPE
${if} $INSTALL_TYPE == ""
StrCpy $INSTALL_TYPE "Live"
ReadEnvStr $R0 SYSTEMDRIVE
StrCpy $INSTDIR "$LOCALAPPDATA\Programs\MyComp\MyApp$INSTALL_TYPE\"
FunctionEnd
!define MUI_PRODUCT "FCDS-RECAP$INSTALL_TYPE"
OutFile "MyApp-$INSTALL_TYPEinstaller.exe"
One of the main errors I get has to do with MUI_PRODUCT and look similar to;
warning 6000: unknown variable/constant "INSTALL_TYPE.lnk" detected, ignoring (FullDeploymentUser.nsi:121)
warning 6000: unknown variable/constant "INSTALL_TYPE" detected, ignoring (FullDeploymentUser.nsi:124)
Two types of comments would be useful;
This is what you are doing wrong...
This is what you should be doing...
As always any help is appreciated.
MUI_PRODUCT is technically not an official NSIS define, some guy just invented it and used it in a guide.
All instructions starting with ! are preprocessor instructions, those and OutFile and File cannot be controlled by ${GetOptions} because they happen at compile time on your developer machine.
I don't really recommend this 3 in 1 installer solution, it is a bit complicated. It is much better to just create 3 different installers:
!ifndef APPTYPE
!error "APPTYPE not defined"
!endif
Name "MyApp ${APPTYPE}"
OutFile "MyApp ${APPTYPE} setup.exe"
InstallDir "$ProgramFiles\MyApp ${APPTYPE}"
Page Directory
Page InstFiles
Section
SetOutPath $InstDir
File /r "c:\myfiles\MyApp\${APPTYPE}\*"
SectionEnd
and then just generate them with makensis -DAPPTYPE=Beta myapp.nsi etc.
If you really want this 3 in 1 style then you need to use the macros in Sections.nsh to manipulate the sections so that only one of them is visible and active. You also need to mark the install somehow (.ini file?) so that your uninstaller also knows which install type it is uninstalling.
I want to run my application immediately after install and I understand the code to do it is as follows:
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
!insertmacro MUI_PAGE_FINISH
Section
CreateShortcut "$DESKTOP\HelloWorldShortcut.lnk" "$INSTDIR\Hello World.exe" "dev03 3"
SectionEnd
Function LaunchLink
ExecShell "" "$DESKTOP\HelloWorldShortcut.lnk"
FunctionEnd
The problem is my installer is a silent installer but the above code adds a page to it.
Is there a way to use a silent installer to also run the application immediately after install?
A silent installer can just run the app as the final step in the last section. Whether or not it is a good idea for a silent installer to start the application is something you should think about, personally I would say no...
Section
SetOutPath $InstDir
File "MyApp.exe"
...
IfSilent "" +2 ; If the installer is always silent then you don't need this check
ExecShell "" "$InstDir\MyApp.exe"
SectionEnd
I need to uninstall previous version if installed already. I have a NSIS script. Here is what I have tried:-
Function UninstallPreviousVersion
ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName"
StrCmp $R0 "" done remove
remove:
DetailPrint "Removing previous installation."
ExecWait '"$INSTDIR\uninst.exe" /S _?=$INSTDIR'
done:
FunctionEnd
But When I run it instead of uninstalling old and install new version. it creates a new folder 'bin' under installation folder.
Any help please?
You might want to read the uninstall directory from the registry in case the old install location is not the same as $instdir but this is not your real problem. Your code does look correct so I suggest you do some "MessageBox debugging" in your uninstaller code...
Is there any way to tell NSIS not to overwrite my start menu shortcut. The reason I don't want it to overwrite is so the user's command line options aren't cleared when they upgrade to a new version. I've tried this to no avail:
Section -AdditionalIcons
SetOverwrite off
CreateDirectory "${START_MENU_DIR}"
CreateShortCut "${START_MENU_LNK}" "$INSTDIR\${PRODUCT_NAME}.exe"
SectionEnd
Why can't you just check with IfFileExists ?
If you wanted to go all out, you could update the path and working dir, but leave the parameters and icon in place, but to do that you would have to call the IShellLink COM interface on your own (With the system plugin or a custom plugin/app)
Here is an example that works:
Section -AdditionalIcons
CreateDirectory "${START_MENU_DIR}"
IfFileExists "${START_MENU_LNK}" SkipShortcut
CreateShortCut "${START_MENU_LNK}" "$INSTDIR\${PRODUCT_NAME}.exe"
SkipShortcut:
SectionEnd