【问题标题】:NSIS Why does CopyFiles work in one example and not the other?NSIS 为什么 CopyFiles 在一个示例中有效,而在另一个示例中无效?
【发布时间】:2017-01-18 16:46:04
【问题描述】:

我在使用 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

我觉得第一个和最后一个示例是做同一件事的两种不同方式。关于为什么第一个示例不起作用的任何说明?

【问题讨论】:

    标签: installation nsis uninstallation


    【解决方案1】:

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

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

    StrCpy $0 "Hello World"
    MessageBox mb_ok $0
    

    完全一样

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

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

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

    NSIS forum 上有一个带有一堆不同解决方案的线程。这是我对这种功能的看法:

    !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
    

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

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

    【讨论】:

    • 您是否不需要担心将参数 $uninstallPath 传递给可能包含空格但没有被引号包围的 CopyFiles?此外,如果不需要引号,为什么通常的做法是围绕存储在注册表中的路径然后删除它们?
    • 即使变量包含空格,您也不必引用变量,它们会在编译器解析您传递给脚本中函数的任何参数很久之后在最终用户机器上展开。任何可以执行的命令在存储在注册表中时都应该被引用,而其他路径(如图标和其他文件)通常不被引用。另见:blogs.msdn.microsoft.com/oldnewthing/20070515-00/?p=26863
    • 我注意到代码有一个小问题。第一个 StrCpy 应该是 StrCpy $1 $0 1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多