I have a script has code to remove an old version that works:
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
ExecWait '"$PreviousUninstaller" /S _?=$INSTDIR'
If I instead code:
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "QuietUninstallString"
ExecWait '"$PreviousUninstaller" _?=$INSTDIR'
That DOES NOT work.
Here's how I'm setting them:
WriteRegStr HKLM "${DSS_REG_UNINSTALL_PATH}" "UninstallString" "$INSTDIR\${DSS_UNINSTALL_FILE}.exe"
WriteRegStr HKLM "${DSS_REG_UNINSTALL_PATH}" "QuietUninstallString" "$INSTDIR\${DSS_UNINSTALL_FILE}.exe /S"
I assume (ha!) that I'm doing something wrong - but what?
Thanks
David
UninstallString works QuietUninstallString not
16 posts
Wrong quotes.
Double quotes are for paths, not the entire command.
The compiler removes the outer set of quotes so your UninstallString value is not actually quoted and that could be problematic if the path contains a space. You get the classic c:\Program Files\App.exe vs c:\Program.exe problem.
When executing you should not add quotes around the variable because it should already be quoted, ExecWait '$PreviousUninstaller _?=$INSTDIR' but $INSTDIR is not really correct here, you should really extract the old path from $PreviousUninstaller.
Double quotes are for paths, not the entire command.
WriteRegStr HKLM "${DSS_REG_UNINSTALL_PATH}" "QuietUninstallString" '"$INSTDIR\${DSS_UNINSTALL_FILE}.exe" /S'UninstallString is also wrong but Windows helps you out and you get lucky.
The compiler removes the outer set of quotes so your UninstallString value is not actually quoted and that could be problematic if the path contains a space. You get the classic c:\Program Files\App.exe vs c:\Program.exe problem.
When executing you should not add quotes around the variable because it should already be quoted, ExecWait '$PreviousUninstaller _?=$INSTDIR' but $INSTDIR is not really correct here, you should really extract the old path from $PreviousUninstaller.
Do you have a code clip you can share to do that path extraction?
And if possible please could you confirm that this is correct?
David
And if possible please could you confirm that this is correct?
WriteRegStr HKLM "${DSS_REG_UNINSTALL_PATH}" "UninstallString" '"$INSTDIR\${DSS_UNINSTALL_FILE}.exe"'
WriteRegStr HKLM "${DSS_REG_UNINSTALL_PATH}" "QuietUninstallString" '"$INSTDIR\${DSS_UNINSTALL_FILE}.exe" /S'
ThanksDavid
I'm sure one of the standard include files can do it or grab PathRemoveArgsAndQuotes from https://gist.github.com/sredna/45e51...44e523f3c31fc1
ReadRegStr $unprev ...And yes, those look correct.
${If} $unprev != ""
PathRemoveArgsAndQuotes $0 $unprev
ExecWait '$unprev _?=$0'
${EndIf}
Just to confirm is this what I need near the beginning:
!include "UtilBonus.nsh"
# Add Path extraction macro
!insertmacro PathRemoveArgsAndQuotes
Then the code you've kindly shown ...
Is that right?
David
!include "UtilBonus.nsh"
# Add Path extraction macro
!insertmacro PathRemoveArgsAndQuotes
Then the code you've kindly shown ...
Is that right?
David
Or just copy that single function, you don't need the entire header.
Odd I included the header and tried to compile my script and got this:
CRCCheck: On
Error: can't change compressor after data already got compressed or header already changed!
Error in script "D:\Users\amonra\Documents\GitHub\DSS\Installers
\DeepSkyStackerInstaller32.nsi" on line 50 -- aborting creation process
I don't understand that at all!
CRCCheck: On
Error: can't change compressor after data already got compressed or header already changed!
Error in script "D:\Users\amonra\Documents\GitHub\DSS\Installers
\DeepSkyStackerInstaller32.nsi" on line 50 -- aborting creation process
I don't understand that at all!
I just copied that into a fifle PathRemove.nsh which I included.
I that had:
# Uninstall previous version silently
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
${If} PreviousUninstaller != ""
${PathRemoveArgsAndQuotes} $0 $PreviousUninstaller
ExecWait '$PreviousUninstaller /S _?=$0'
${EndIf}
and got this:
ReadRegStr $PreviousUninstaller HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\DeepSkyStacker32\UninstallString
!insertmacro: _If
!insertmacro: end of _If
!insertmacro: PathRemoveArgsAndQuotes
warning 6000: unknown variable/constant "{in}" detected, ignoring (macro:PathRemoveArgsAndQuotes:1)
Push: ${in}
Call "PathRemoveArgsAndQuotes"
Pop: $PreviousUninstaller
!insertmacro: end of PathRemoveArgsAndQuotes
ExecWait: "$PreviousUninstaller /S _?=$0" (->)
!insertmacro: _EndIf
!insertmacro: end of _EndIf
What did I do wrong?
David
And then when I ran the installer, I saw this:
Execute: ${in} /S _?=
which surely isn't right!!!
I that had:
# Uninstall previous version silently
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
${If} PreviousUninstaller != ""
${PathRemoveArgsAndQuotes} $0 $PreviousUninstaller
ExecWait '$PreviousUninstaller /S _?=$0'
${EndIf}
and got this:
ReadRegStr $PreviousUninstaller HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\DeepSkyStacker32\UninstallString
!insertmacro: _If
!insertmacro: end of _If
!insertmacro: PathRemoveArgsAndQuotes
warning 6000: unknown variable/constant "{in}" detected, ignoring (macro:PathRemoveArgsAndQuotes:1)
Push: ${in}
Call "PathRemoveArgsAndQuotes"
Pop: $PreviousUninstaller
!insertmacro: end of PathRemoveArgsAndQuotes
ExecWait: "$PreviousUninstaller /S _?=$0" (->)
!insertmacro: _EndIf
!insertmacro: end of _EndIf
What did I do wrong?
David
And then when I ran the installer, I saw this:
Execute: ${in} /S _?=
which surely isn't right!!!
1) "change compressor after data already got compressed" means that the order of things in your .NSI is wrong. You must set the Compressor and Unicode attributes at the top of the .NSI before !includes and functions.
2) ${in} is a bug, I changed the code slightly on Github after I wrote it. I have fixed it on Github now, try again (sorry).
2) ${in} is a bug, I changed the code slightly on Github after I wrote it. I have fixed it on Github now, try again (sorry).
My code reads thus:
Whereas if there is a previous install I see;
David
When I run the installer and if there is no previous install (No uninstall string) I see:
# Uninstall previous version silently
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
${If} PreviousUninstaller != ""
${PathRemoveArgsAndQuotes} $0 $PreviousUninstaller
ExecWait '$PreviousUninstaller /S _?=$0'
${EndIf}
when I run the installer.Execute: /S _?=
Whereas if there is a previous install I see;
I thought your parser returned just the path (without the .exe). AFAICT it just returns the string it was provided which doesn't seem right?Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?=C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe
David
1) ${If} PreviousUninstaller != "" should cover this but there is a missing $, it should be $PreviousUninstaller != "".
2) Yes, my fault again I'm afraid, I just was not thinking about things correctly. You do want just the path without the filename.
You have two options.
A) Just add "\..":
or
B) Remove the filename. FileFunc.nsh has a GetParent or you can use https://nsis.sourceforge.io/Get_parent_directory#.
2) Yes, my fault again I'm afraid, I just was not thinking about things correctly. You do want just the path without the filename.
You have two options.
A) Just add "\..":
ReadRegStr $PreviousUninstaller ...but I don't remember if that actually works (and I can't test right now). It probably does work though (it does not, the uninstaller is picky).
${If} $PreviousUninstaller != ""
PathRemoveArgsAndQuotes $0 $PreviousUninstaller
ExecWait '$PreviousUninstaller _?=$0\..'
${EndIf}
or
B) Remove the filename. FileFunc.nsh has a GetParent or you can use https://nsis.sourceforge.io/Get_parent_directory#.
Results in the following if the product is already installed:
# Uninstall previous version silently
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
${If} $PreviousUninstaller != ""
${PathRemoveArgsAndQuotes} $0 $PreviousUninstaller
${GetParent} $0 $R0
ExecWait '$PreviousUninstaller /S _?="$R0"'
${EndIf}
Which I think is correct? Should _? be quoted or not?Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?="C:\Program Files (x86)\DeepSkyStacker (32 bit)"
And no action if the product wasn't installed.
Dave
_?=
it must be the last parameter used in the command line and must not contain any quotes, even if the path contains spaces.
Argghh! That breaks big time if the Uninstall String isn't quoted (yes I know that isn't right but our first install scipts did it wrong!) ...
Dave
Is there an easy way to fix that up - I'm really struggling with the string functions here!Execute: C:\Program Files (x86)\DeepSkyStacker\DeepSkyStackerUninstaller.exe /S _?="C:"
Dave
OK I've now got it working correctly - this is the final code:
Wish that hadn't been quite such a struggle!
Thanks, David
This results in the following when the installer is run:
# Uninstall previous version silently
ReadRegStr $PreviousUninstaller HKLM ${DSS_REG_UNINSTALL_PATH} "UninstallString"
${If} $PreviousUninstaller != ""
#
# If the Uninstall string is malformed (executable name isn't double quoted)
# we need to wrap in in double quotes
#
StrCpy $0 $PreviousUninstaller 1
${If} '"' != $0
StrCpy $PreviousUninstaller '"$PreviousUninstaller"'
${Endif}
#
# Now strip out the directory name to feed to _? parameter
#
${PathRemoveArgsAndQuotes} $0 $PreviousUninstaller
${GetParent} $0 $R0
#
# Finally uninstall the previous version silently
#
ExecWait '$PreviousUninstaller /S _?=$R0'
${EndIf}
With _? paramter specifically NOT being quoted!Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?=C:\Program Files (x86)\DeepSkyStacker (32 bit)
Wish that hadn't been quite such a struggle!
Thanks, David
And now we have https://nsis.sourceforge.io/Auto-uni...installing_newOriginally Posted by perdrix View PostWish that hadn't been quite such a struggle!