Old 11th June 2019, 13:26   #1
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
UninstallString works QuietUninstallString not

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
perdrix is offline   Reply With Quote
Old 11th June 2019, 14:15   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
Wrong quotes.

Double quotes are for paths, not the entire command.

Quote:
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.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 12th June 2019, 10:29   #3
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
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?

code:
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'



Thanks
David
perdrix is offline   Reply With Quote
Old 12th June 2019, 14:13   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
I'm sure one of the standard include files can do it or grab PathRemoveArgsAndQuotes from https://gist.github.com/sredna/45e51...44e523f3c31fc1

Quote:
ReadRegStr $unprev ...
${If} $unprev != ""
PathRemoveArgsAndQuotes $0 $unprev
ExecWait '$unprev _?=$0'
${EndIf}
And yes, those look correct.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 12th June 2019, 16:47   #5
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
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
perdrix is offline   Reply With Quote
Old 12th June 2019, 17:09   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
Or just copy that single function, you don't need the entire header.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 12th June 2019, 17:58   #7
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
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!
perdrix is offline   Reply With Quote
Old 12th June 2019, 18:28   #8
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
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!!!
perdrix is offline   Reply With Quote
Old 12th June 2019, 19:16   #9
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
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).

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 12th June 2019, 20:24   #10
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
My code reads thus:

code:

# 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 and if there is no previous install (No uninstall string) I see:

code:
Execute: /S _?=


when I run the installer.

Whereas if there is a previous install I see;

code:
Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?=C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe


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?

David
perdrix is offline   Reply With Quote
Old 12th June 2019, 23:30   #11
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
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 "\..":

Quote:
ReadRegStr $PreviousUninstaller ...
${If} $PreviousUninstaller != ""
PathRemoveArgsAndQuotes $0 $PreviousUninstaller
ExecWait '$PreviousUninstaller _?=$0\..'
${EndIf}
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).

or

B) Remove the filename. FileFunc.nsh has a GetParent or you can use https://nsis.sourceforge.io/Get_parent_directory#.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 13th June 2019, 11:49   #12
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
code:

# 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}



Results in the following if the product is already installed:

code:
Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?="C:\Program Files (x86)\DeepSkyStacker (32 bit)"


Which I think is correct? Should _? be quoted or not?

And no action if the product wasn't installed.

Dave
perdrix is offline   Reply With Quote
Old 13th June 2019, 12:19   #13
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
_?=
Quote:
it must be the last parameter used in the command line and must not contain any quotes, even if the path contains spaces.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 13th June 2019, 12:22   #14
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
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!) ...

code:
Execute: C:\Program Files (x86)\DeepSkyStacker\DeepSkyStackerUninstaller.exe /S _?="C:"


Is there an easy way to fix that up - I'm really struggling with the string functions here!

Dave
perdrix is offline   Reply With Quote
Old 13th June 2019, 13:18   #15
perdrix
Junior Member
 
Join Date: Jun 2019
Posts: 9
OK I've now got it working correctly - this is the final code:

code:

# 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}



This results in the following when the installer is run:

code:
Execute: "C:\Program Files (x86)\DeepSkyStacker (32 bit)\DSS32-Remove.exe" /S _?=C:\Program Files (x86)\DeepSkyStacker (32 bit)


With _? paramter specifically NOT being quoted!

Wish that hadn't been quite such a struggle!

Thanks, David
perdrix is offline   Reply With Quote
Old 14th June 2019, 18:53   #16
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,090
Quote:
Originally Posted by perdrix View Post
Wish that hadn't been quite such a struggle!
And now we have https://nsis.sourceforge.io/Auto-uni...installing_new

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump