NSI脚本:使用insertmacro从另一个宏调用一个宏会产生错误

时间:2014-01-20 06:51:43

标签: macros nsis

我试图在NSI脚本中调用另一个宏。这两个宏都有MB_OKCANCEL。编译时会出现以下错误:

**  [exec]错误:标签“abort_inst:”已在函数中声明 **

   !include "MUI2.nsh"
OutFile abc.exe

!macro installA
MessageBox MB_OKCANCEL "A?" IDOK lblinstall IDCANCEL abort_inst
abort_inst:
          ABORT       
     GoTo lblinstall 
lblinstall:
!macroend

!macro uninstallA
MessageBox MB_OKCANCEL "?" IDOK install_A IDCANCEL abort_uninstall
abort_uninstall:
          ABORT
install_A:
  !insertmacro installA
!macroend


Function .onInit
ReadRegStr $0 HKLM "x" "version"
${If} $0 == ""  
    !insertmacro installA 
${Else}
    !insertmacro uninstallA
${EndIf} 


FunctionEnd
Section "required" main_section
SectionEnd

请帮忙

3 个答案:

答案 0 :(得分:0)

(下次请确保您的代码不会出现奇怪的换行符)

插入宏时,!macro!macroend之间的所有代码都将替换您的!insertmacro。因此,你不应该在宏中使用静态标签 - 你只能插入宏一次(使宏没有意义!)你可以使用相对跳跃(例如Goto +2)或通过向标签添加参数来使标签动态化,例如:

!macro myMacro param1
    ${param1}_loop:
    MessageBox MB_YESNO "Loop this message?" IDYES ${param1}_loop

    # some more code
    ${param1}_end:
!macroend

但是,由于您没有将任何参数传递给宏,为什么不简单地使用函数?

Function installA
    # your code here
Function

Function uninstallA
    # your code here
    Call installA
FunctionEnd

答案 1 :(得分:0)

通过将一个宏转换为函数来解决这个问题,正如@idelberg

所建议的那样

答案 2 :(得分:0)

同样,只要您使用宏,就不能使用静态标签。静态标签只能在函数或节中使用一次。您对宏的使用将转换为以下内容:

Function .onInit
ReadRegStr $0 HKLM "x" "version"
${If} $0 == ""  
    MessageBox MB_OKCANCEL "A?" IDOK lblinstall IDCANCEL abort_inst
    abort_inst:
    Abort       
    Goto lblinstall 
    lblinstall: # FIRST TIME USE
${Else}
    MessageBox MB_OKCANCEL "?" IDOK install_A IDCANCEL abort_uninstall
    abort_uninstall:
    Abort
    install_A:
    MessageBox MB_OKCANCEL "A?" IDOK lblinstall IDCANCEL abort_inst
    abort_inst:
    Abort       
    Goto lblinstall 
    lblinstall: # SECOND TIME USE
${EndIf}
FunctionEnd

因此,由于lblinstall标签被使用了两次,因此无效。相反,你可以这样做:

Function installA
    MessageBox MB_OKCANCEL "A?" IDOK lblinstall 
    Abort

    lblinstall:
FunctionEnd

Function uninstallA
    MessageBox MB_OKCANCEL "?" IDOK install_A
    Abort

    install_A:
    Call installA
FunctionEnd

Function .onInit
    ReadRegStr $0 HKLM "x" "version"
    ${If} $0 == ""  
        Call installA 
    ${Else}
        Call uninstallA
    ${EndIf}
FunctionEnd

(我也可以自由地从你的例子中删除一些不必要的标签)