user870130
user870130

Reputation: 575

NSIS Why does CopyFiles work in one example and not the other?

I am having difficulty using the CopyFiles command and the value I read from the UninstallString registry. The value of the UninstallString is "C:\myapp\uninstall.exe" (with quotes).

If I try the following it does not work.

CopyFiles $uninstallPath "C:\Temp" # Does not work

Next, I edit the registry and remove the quotes from UninstallString's value so it is C:\myapp\uninstall.exe.

The following works, but it is not surrounded by quotes.

CopyFiles $uninstallPath "C:\Temp" # Works

Now I add quotes around the variable and it works.

CopyFiles "$uninstallPath" "C:\Temp" # Works

I feel like the first and last examples are two different ways of doing the same thing. Any clarity on why the first example does not work?

Upvotes: 0

Views: 857

Answers (1)

Anders
Anders

Reputation: 101569

You are comparing apples to oranges, or in your case, quotes vs. stripped quotes.

The outermost quotes on parameters in your .nsi are removed by the compiler so

StrCpy $0 "Hello World"
MessageBox mb_ok $0

is exactly the same as

StrCpy $0 "Hello World"
MessageBox mb_ok "$0"

However, if you read a string into a variable on the users machine then no quotes are removed:

StrCpy $0 '"Hello World"' ; Pretending that we read "Hello World" (with quotes) from somewhere
MessageBox mb_ok $0

There is a thread with a bunch of different solutions on the NSIS forum. Here is my take on that type of function:

!define PathUnquoteSpaces '!insertmacro PathUnquoteSpaces '
Function PathUnquoteSpaces
Exch $0
Push $1
StrCpy $1 $0 1
StrCmp $1 '"' 0 ret
StrCpy $1 $0 "" -1
StrCmp $1 '"' 0 ret
StrCpy $0 $0 -1 1
ret:
Pop $1
Exch $0
FunctionEnd
!macro PathUnquoteSpaces var
Push ${var}
Call PathUnquoteSpaces
Pop ${var}
!macroend


Section 
!macro Test path
StrCpy $0 '${Path}'
StrCpy $1 $0
${PathUnquoteSpaces} $0
DetailPrint |$1|->|$0|
!macroend
!insertmacro Test 'c:\foo'
!insertmacro Test 'c:\foo bar'
!insertmacro Test '"c:\foo"'
!insertmacro Test '"c:\foo bar"'
SectionEnd

Your code should then look something like this after copying my function into your .nsi:

ReadRegStr $uninstallPath HKLM "Sofware\...\YourAppUninstKey" "UninstallString"
${PathUnquoteSpaces} $uninstallPath
CopyFiles $uninstallPath "C:\Temp"

Upvotes: 1

Related Questions