【问题标题】:Detecting if a program is already installed with NSIS检测一个程序是否已经安装了 NSIS
【发布时间】:2010-10-04 01:47:45
【问题描述】:

我正在使用 NSIS 为程序创建安装程序,检测该程序是否已安装的最佳方法是什么?另外,由于我从 autorun.inf 运行安装程序,如果它找到已安装的副本,我可以立即退出安装程序吗?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: windows nsis autorun


    【解决方案1】:

    这个怎么样。 我在一个旧的 NSIS 脚本中有这个。

    ; Check to see if already installed
      ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\<YOUR-APP-NAME>" "UninstallString"
      IfFileExists $R0 +1 NotInstalled
      messagebox::show MB_DEFBUTTON4|MB_TOPMOST "<YOUR-APP-NAME>" \
        "0,103" \
        "<YOUR-APP-NAME> is already installed." \
        "Launch Uninstall" "Cancel"
        Pop $R1
      StrCmp $R1 2 Quit +1
      Exec $R0
    Quit:
      Quit
    
    NotInstalled:
    

    【讨论】:

    • 您提到了启动卸载。通过使用上面的代码,我无法真正在我的 .nsi 脚本中调用 Uninstall。如果我的程序已经安装,你能告诉我如何调用 Uninstall 吗?
    • 我不得不将messagebox::show 行更改为MessageBox MB_YESNO "${YOUR_APP_NAME} is already installed. Uninstall the existing version?" /SD IDYES IDNO Quit
    • 并非总是如此。某些软件在卸载下没有直接的 ,例如,Visual C++ 可再发行软件。在这种情况下,我们可能需要遍历 Uninstall 下的所有键,并检查值名称“DisplayName”的值数据
    【解决方案2】:

    我一直在使用更复杂的测试,它还检查已安装软件的版本:

    !define PRODUCT_VERSION "1.2.0"
    
    !include "WordFunc.nsh"
      !insertmacro VersionCompare
    
    Var UNINSTALL_OLD_VERSION
    
    ...
    
    Section "Core System" CoreSystem
      StrCmp $UNINSTALL_OLD_VERSION "" core.files
      ExecWait '$UNINSTALL_OLD_VERSION'
    
    core.files:
    
      ...
      WriteRegStr HKLM "Software\${PRODUCT_REG_KEY}" "" $INSTDIR
      WriteRegStr HKLM "Software\${PRODUCT_REG_KEY}" "Version" "${PRODUCT_VERSION}"
      ...
    SectionEnd
    
    ...
    
    Function .onInit
      ;Check earlier installation
      ClearErrors
      ReadRegStr $0 HKLM "Software\${PRODUCT_REG_KEY}" "Version"
      IfErrors init.uninst ; older versions might not have "Version" string set
      ${VersionCompare} $0 ${PRODUCT_VERSION} $1
      IntCmp $1 2 init.uninst
        MessageBox MB_YESNO|MB_ICONQUESTION "${PRODUCT_NAME} version $0 seems to be already installed on your system.$\nWould you like to proceed with the installation of version ${PRODUCT_VERSION}?" \
            IDYES init.uninst
        Quit
    
    init.uninst:
      ClearErrors
      ReadRegStr $0 HKLM "Software\${PRODUCT_REG_KEY}" ""
      IfErrors init.done
      StrCpy $UNINSTALL_OLD_VERSION '"$0\uninstall.exe" /S _?=$0'
    
    init.done:
    FunctionEnd
    

    你当然要填写细节,这只给你一个粗略的骨架。

    【讨论】:

      【解决方案3】:

      创建卸载程序后,在注册表中创建产品名称条目

      !define PRODUCT_UNINST_ROOT_KEY "HKLM"
      !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANY_NAME} ${PRODUCT_NAME}"
      Section -Post
        SetShellVarContext current
        WriteUninstaller "${UNINST_PATH}\uninst.exe"
        WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
      

      查看产品是否已安装

      Function IsProductInstalled
        ClearErrors
        ReadRegStr $2 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName"  
        StrCmp $2 "" exit
      

      在你的卸载中你应该这样做

      Section Uninstall
          DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
      

      【讨论】:

        【解决方案4】:

        这通常通过让 NSIS 在安装时为您的产品插入一个注册表项来完成。然后,这是一种简单的方法来检测该注册表项是否存在,如果存在,则保释

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多