代码之家  ›  专栏  ›  技术社区  ›  user8128167

安装两个应用程序,但第二个应用程序会在“浏览目录”中附加第一个应用程序名称

  •  0
  • user8128167  · 技术社区  · 5 年前

    请注意,我最初为两个基于 https://nsis.sourceforge.io/Two_installations_in_one_installer https://www.codeproject.com/Articles/24187/Creating-an-Installer?msg=5782957#xx5782957xx

    我遇到的问题是,当我进入第二个license manager应用程序时,我单击以浏览自定义文件夹,并创建一个新的自定义文件夹,当我在“浏览”上按“确定”时,它会返回此自定义文件夹,但随后会附加应用程序名称。例如,当我从“浏览自定义目录”对话框返回时,它不会返回,例如:

    C:\Tools\FlexLM
    

    它将返回以下内容,即使我没有添加“MyApp”部分:

    C:\Tools\FlexLM\MyApp
    

    请在此处找到完整的源代码:

    !include "LogicLib.nsh"
    !include "Sections.nsh"
        
    ;Include Modern UI
    !include "MUI2.nsh"
    
    !define MAJOR_VERSION "1" 
    !define MINOR_VERSION "2" 
    !define PATCH_VERSION "3" 
    !define BUILD_VERSION "4" 
        
    !define APP_COPYRIGHT "MyApp © MyCompany 2021"
    !define COMPANY_NAME "MyCompany"
    !define FLEX_LM "FlexLM"        
    !define FLEX_DIR "FlexSQI"            
    !define LANG_ENGLSH "English" 
    !define PRODUCT_NAME "MyApp"
    !define PRODUCT_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${BUILD_VERSION}"
    !define SETUP_NAME "MyAppSetup.exe"
    
    BrandingText "MyCompany"
    
    OutFile ${SETUP_NAME}
    Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
    
    InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}"
    InstallDirRegKey HKLM "Software\$PRODUCT_NAME" ""
    ShowInstDetails hide
    ShowUnInstDetails hide
    
    SetCompressor /SOLID lzma
    SetCompressorDictSize 12
    
    Var MyAppCheckboxState
    Var FlexLmCheckboxState
    
    ;Request application privileges for Windows 
    RequestExecutionLevel admin
    
    !insertmacro MUI_PAGE_WELCOME
    !insertmacro MUI_PAGE_LICENSE "MyAppLicense.txt"
    
    !define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesCheck
    !define MUI_PAGE_CUSTOMFUNCTION_LEAVE ComponentsLeave
    !insertmacro MUI_PAGE_COMPONENTS   
     
    ## This is the title on the MyApp Directory page
    !define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_A)"
     
    !define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesA
    !insertmacro MUI_PAGE_DIRECTORY
    !insertmacro MUI_PAGE_INSTFILES
     
    ## This is the title on the FlexLM Directory page
    !define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_B)"
     
    !define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesB
    !insertmacro MUI_PAGE_DIRECTORY
    !insertmacro MUI_PAGE_INSTFILES
    
    !define MUI_PAGE_CUSTOMFUNCTION_LEAVE DeleteSectionsINI
    !insertmacro MUI_PAGE_FINISH
    
    !insertmacro MUI_UNPAGE_WELCOME
    !insertmacro MUI_UNPAGE_CONFIRM
    !insertmacro MUI_UNPAGE_INSTFILES
    !insertmacro MUI_UNPAGE_FINISH
    
    ;--------------------------------
    ;Languages
    
    !insertmacro MUI_LANGUAGE "English"
    
    ;--------------------------------
    
    LangString NoSectionsSelected ${LANG_ENGLSH} "You haven't selected any sections!"
    
    LangString MUI_DIRECTORYPAGE_TEXT_TOP_A ${LANG_ENGLSH} "Setup will install \
    ${PRODUCT_NAME} in the following folder..."
    LangString MUI_DIRECTORYPAGE_TEXT_TOP_B ${LANG_ENGLSH} "Setup will install \
    ${FLEX_LM} in the following folder..."
    
    ;--------------------------------
    ; Settings
     
    !define PROG1_InstDir    "$PROGRAMFILES64\${PRODUCT_NAME}"
    !define PROG1_StartIndex ${SEC1}
    !define PROG1_EndIndex   ${SEC1}
     
    !define PROG2_InstDir "C:\${FLEX_DIR}"
    !define PROG2_StartIndex ${SEC3}
    !define PROG2_EndIndex   ${SEC3}
    
    ;--------------------------------
    ; Start sections
    
    Section "MyApp" SEC1
      StrCpy $MyAppCheckboxState ${BST_CHECKED}
      ${If} $MyAppCheckboxState == ${BST_CHECKED}
        ##All the files in Group 1 will be installed to the same location, $INSTDIR
        SetOutPath "$INSTDIR"
    
        # specify files to go in output path
        File config.dat 
        File MyApp.exe
        File ReleaseNotes.txt
        File MyCompany_LandingPage_114.bmp
        File MyAppLicense.txt  
      
        # create a shortcut named "new shortcut" in the start menu programs directory
        CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$PROGRAMFILES64\${PRODUCT_NAME}\${PRODUCT_NAME}.exe" 
    
        # Add application to registry  
        ClearErrors
        WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Company Name' "${COMPANY_NAME}"
        WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'Version' "${PRODUCT_VERSION}"
        WriteRegStr HKCU "SOFTWARE\${PRODUCT_NAME}" 'AppID' "{0be21143-9089-47fa-9736-c45609d13d70}"
     
        # Add program to Add/Remove programs 
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "DisplayIcon" "$PROGRAMFILES64\${PRODUCT_NAME}\${PRODUCT_NAME}.exe"
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "AppID" "{0be21143-9089-47fa-9736-c45609d13d70}"              
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "DisplayName" "${PRODUCT_NAME}"
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "DisplayVersion" "${PRODUCT_VERSION}"                 
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "InstallLocation" "$INSTDIR"                      
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                       "Publisher" "${COMPANY_NAME}"                 
        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                         "UninstallString" "$\"$INSTDIR\uninstaller.exe$\""
    
        # define uninstaller name
        WriteUninstaller $INSTDIR\uninstaller.exe        
    
      ${EndIf}
    
      # messagebox mb_ok sec1
    SectionEnd
    
    Section "FlexLM" SEC3
      StrCpy $FlexLmCheckboxState ${BST_CHECKED}
      ${If} $FlexLmCheckboxState == ${BST_CHECKED}    
        ##All the files in Group 2 will be installed to the same location, $INSTDIR
        SetOutPath "$INSTDIR"
    
        File installs.exe
        File lmdown.exe
        File lmflex.exe
        
        # define uninstaller name
        WriteUninstaller $INSTDIR\uninstaller.exe
    
      ${EndIf}    
    
      # messagebox mb_ok sec3
     
    SectionEnd
    
    ;--------------------------------
    ;Descriptions
    
      ;Language strings
      LangString DESC_SecMyApp ${LANG_ENGLISH} "MyAppTM software is an easy-to-use suite of tools."
      LangString DESC_SecFlexLM ${LANG_ENGLISH} "FlexSQI contains all the files necessary to implement the FlexLM license server."
    
      ;Assign language strings to sections
      !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN    
        !insertmacro MUI_DESCRIPTION_TEXT ${SEC1} $(DESC_SecMyApp)
        !insertmacro MUI_DESCRIPTION_TEXT ${SEC3} $(DESC_SecFlexLM)
      !insertmacro MUI_FUNCTION_DESCRIPTION_END
    
    Section "Uninstall"  
    
      # Always delete uninstaller first
      Delete $INSTDIR\uninstaller.exe
     
      # now delete installed files and registry keys for MyApp
      Delete $INSTDIR\config.dat
      Delete $INSTDIR\MyApp.exe
      Delete $INSTDIR\ReleaseNotes.txt
      Delete $INSTDIR\MyCompany_LandingPage_114.bmp
      Delete $INSTDIR\MyAppLicense.txt
      Delete "$SMPROGRAMS\MyApp.lnk"
      DeleteRegKey HKCU "SOFTWARE\${PRODUCT_NAME}"
      DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
      DeleteRegKey /ifempty HKCU "Software\Modern UI Test"       
            
      # now delete installed files and registry keys for FlexLM
      Delete $INSTDIR\lmdown.exe
      Delete $INSTDIR\lmflex.exe
      Delete $INSTDIR\installs.exe
    
      # Delete the QI Pro and FlexLM directories
      RMDir $INSTDIR
    
    SectionEnd
    
    ;--------------------------------
    ; Please don`t modify below here unless you`re a NSIS 'wiz-kid'
     
    ## Create $PLUGINSDIR
    Function .onInit
      InitPluginsDir
    
      SetOutPath $TEMP
      File /oname=spltmp.bmp "MyCompany_LandingPage_114.bmp"
    
      splash::show 2000 $TEMP\spltmp
    
      Pop $0 ; $0 has '1' if the user closed the splash screen early,
      ; '0' if everything closed normally, and '-1' if some error occurred.
    
      Delete $TEMP\spltmp.bmp  
    FunctionEnd
            
    ## If user goes back to this page from 1st Directory page
    ## we need to put the sections back to how they were before
    Var IfBack
    Function SelectFilesCheck
      StrCmp $IfBack 1 0 NoCheck
      ;Call ResetFiles
      NoCheck:
    FunctionEnd
     
    ## Also if no sections are selected, warn the user!
    Function ComponentsLeave
    Push $R0
    Push $R1
     
     Call IsPROG1Selected
      Pop $R0
     Call IsPROG2Selected
      Pop $R1
     StrCmp $R0 1 End
     StrCmp $R1 1 End
      Pop $R1
      Pop $R0
     MessageBox MB_OK|MB_ICONEXCLAMATION "$(NoSectionsSelected)"
     Abort
     
    End:
    Pop $R1
    Pop $R0
    FunctionEnd
        
    Function IsPROG1Selected
    Push $R0
    
     StrCpy $R0 ${PROG1_StartIndex} # Group 1 start
     
       SectionGetFlags 0 $R0            # Get section flags
        IntOp $R0 $R0 & ${SF_SELECTED}
        StrCmp $R0 ${SF_SELECTED} 0 +3      # If section is selected, done
         StrCpy $R0 1
     
    Exch $R0
    FunctionEnd
     
    Function IsPROG2Selected
    Push $R1
     
     StrCpy $R1 ${PROG2_StartIndex}    # Group 2 start
     
       IntOp $R1 $R1 + 1
       SectionGetFlags 1 $R1            # Get section flags
        IntOp $R1 $R1 & ${SF_SELECTED}
        StrCmp $R1 ${SF_SELECTED} 0 +3      # If section is selected, done
         StrCpy $R1 1
     
    Exch $R1
    FunctionEnd
    
    ## Here we are selecting first sections to install
    ## by unselecting all the others!
    Function SelectFilesA
     
     # If user clicks Back now, we will know to reselect Group 2`s sections for
     # Components page
     StrCpy $IfBack 1
     
     # We need to save the state of the Group 2 Sections
     # for the next InstFiles page
    Push $R0
    Push $R1
     
     StrCpy $R0 ${PROG2_StartIndex} # Group 2 start
     
    ;  Loop:
    ;   IntOp $R0 $R0 + 1
    ;   SectionGetFlags $R0 $R1                 # Get section flags
    ;    WriteINIStr "$PLUGINSDIR\sections.ini" Sections $R0 $R1 # Save state
    ;    !insertmacro UnselectSection $R0               # Then unselect it
    ;    StrCmp $R0 ${PROG2_EndIndex} 0 Loop
     
     # Don`t install prog 1?
     Call IsPROG1Selected
     Pop $R0
     StrCmp $R0 1 +4
      Pop $R1
      Pop $R0
      Abort
     
     # Set current $INSTDIR to PROG1_InstDir define
     StrCpy $INSTDIR "${PROG1_InstDir}"
     
    Pop $R1
    Pop $R0
    FunctionEnd
     
    ## Here we need to unselect all Group 1 sections
    ## and then re-select those in Group 2 (that the user had selected on
    ## Components page)
    Function SelectFilesB
    Push $R0
    ;Push $R1
     
     StrCpy $R0 ${PROG1_StartIndex}    # Group 1 start
     
    ;  Loop:
    ;   IntOp $R0 $R0 + 1
    ;    !insertmacro UnselectSection $R0       # Unselect it
    ;    StrCmp $R0 ${PROG1_EndIndex} 0 Loop
     
    ; Call ResetFiles
     
     # Don't install prog 2?
     Call IsPROG2Selected
     Pop $R0
     StrCmp $R0 1 +4
      Pop $R1
      Pop $R0
      Abort
     
     # Set current $INSTDIR to PROG2_InstDir define
     StrCpy $INSTDIR "${PROG2_InstDir}"
     
    ;Pop $R1
    Pop $R0
    FunctionEnd
    ## Here we are deleting the temp INI file at the end of installation
    Function DeleteSectionsINI
     FlushINI "$PLUGINSDIR\Sections.ini"
     Delete "$PLUGINSDIR\Sections.ini"
    FunctionEnd
    

    请注意,我认为问题可能在以下文件中:

    ~\NSIS\Contrib\Modern UI 2\Pages\Directory.nsh
    

    !macro MUI_FUNCTION_DIRECTORYPAGE PRE SHOW LEAVE
    
      Function "${PRE}"
        !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
        !insertmacro MUI_HEADER_TEXT_PAGE $(MUI_${MUI_PAGE_UNINSTALLER_PREFIX}TEXT_DIRECTORY_TITLE) $(MUI_${MUI_PAGE_UNINSTALLER_PREFIX}TEXT_DIRECTORY_SUBTITLE)
      FunctionEnd
    
      Function "${SHOW}"
      
        ;Get control handles
        FindWindow $mui.DirectoryPage "#32770" "" $HWNDPARENT
        GetDlgItem $mui.DirectoryPage.Text $mui.DirectoryPage 1006
        GetDlgItem $mui.DirectoryPage.DirectoryBox $mui.DirectoryPage 1020
        GetDlgItem $mui.DirectoryPage.Directory $mui.DirectoryPage 1019
        GetDlgItem $mui.DirectoryPage.BrowseButton $mui.DirectoryPage 1001
        GetDlgItem $mui.DirectoryPage.SpaceRequired $mui.DirectoryPage 1023
        GetDlgItem $mui.DirectoryPage.SpaceAvailable $mui.DirectoryPage 1024
      
        !ifdef MUI_DIRECTORYPAGE_BGCOLOR
          !insertmacro MUI_DEFAULT MUI_DIRECTORYPAGE_TEXTCOLOR ""
          SetCtlColors $mui.DirectoryPage.Directory "${MUI_DIRECTORYPAGE_TEXTCOLOR}" "${MUI_DIRECTORYPAGE_BGCOLOR}"
        !endif
        
        !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
      FunctionEnd
    
      Function "${LEAVE}"
        !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
      FunctionEnd
    
    !macroend
    

    但是当我看到上面的内容时,我仍然不清楚如何将MyApp名称添加到目录字符串的末尾。

    0 回复  |  直到 5 年前
        1
  •  0
  •   user8128167    5 年前

    NSIS Directory Page after Browse for install dir "${PRODUCT_NAME}" is added after selection

    所以在我的例子中,我需要添加一个:

    InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}\"