NSIS 为什么 CopyFiles 在一个例子中起作用而在另一个例子中不起作用?

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

我在使用 CopyFiles 命令和从 UninstallString 注册表中读取的值时遇到困难。 UninstallString 的值为 "C:\myapp\uninstall.exe"(带引号)。

如果我尝试以下方法,它不起作用。

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

接下来,我编辑注册表并从 UninstallString 的值中删除引号,使其成为 C:\myapp\uninstall.exe

下面的作品,但没有用引号引起来。

CopyFiles $uninstallPath "C:\Temp" # Works

现在我在变量周围添加引号并且它起作用了。

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

我觉得第一个和最后一个例子是做同一件事的两种不同方式。是否清楚为什么第一个示例不起作用?

您是在将苹果与橙子进行比较,或者在您的情况下,是引用与剥离引号。

编译器删除了 .nsi 中参数的最外层引号,因此

StrCpy [=10=] "Hello World"
MessageBox mb_ok [=10=]

完全一样
StrCpy [=11=] "Hello World"
MessageBox mb_ok "[=11=]"

但是,如果您将字符串读入用户计算机上的变量,则不会删除任何引号:

StrCpy [=12=] '"Hello World"' ; Pretending that we read "Hello World" (with quotes) from somewhere
MessageBox mb_ok [=12=]

NSIS forum 上有一个线程,其中包含一堆不同的解决方案。这是我对这类函数的看法:

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


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

将我的函数复制到您的 .nsi 后,您的代码应该如下所示:

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