【发布时间】:2017-06-26 15:21:11
【问题描述】:
我想用 NSIS 静默安装 Visual C++ Redistributable Packages for Visual Studio 2013。
但是,没有返回正确的退出代码。我测试了几种类型的变化。我想出的最好的是:
DetailPrint "Installing VC++ 2005"
File "${STOCKINPUTFOLDER}\bin\Debug\vcredist_x86.EXE"
ClearErrors
ExecWait "$OUTDIR\vcredist_x86.EXE /q:a /c:$\"msiexec /i vcredist.msi /qb /norestart$\"" $0 ; also can use /qn
;do not delete the file out-rightly so that evaluation of IfErrors below is clean
IfErrors execError noError
execError:
Goto ShortEndInstall
ShortEndInstall:
MessageBox MB_OK|MB_ICONEXCLAMATION "ShortEndInstall"
Delete "$OUTDIR\vcredist_x86.EXE" ;we did not delete the file outrightly so that evaluation of IfErrors is clean
Quit
noError:
${If} $0 != 0
MessageBox MB_OK|MB_ICONEXCLAMATION "You did not complete the installation of the VC++ 2005 re-distributable. Installation will now abort. Return code $0"
Goto ShortEndInstall
${EndIf}
MessageBox MB_OK|MB_ICONEXCLAMATION "No error"
Delete "$OUTDIR\vcredist_x86.EXE" ;we did not delete the file outrightly so that evaluation of IfErrors is clean
但是当我故意点击VC++2005安装的“取消”按钮时,NSIS仍然认为安装成功(我在指令MessageBox MB_OK|MB_ICONEXCLAMATION "No error"得到对话框)
我怎样才能准确正确地获得返回的错误(例如,当我自己“取消”安装时)?
编辑:
在@Anders 的帮助下,我现在得到了以下内容,但仍然失败(即not installed,即使 VC++ 2005 安装已完成。我还尝试了不同的命令行选项来安装 VC++2005)
!include LogicLib.nsh
!include WordFunc.nsh
!define VERSION "8.1.0.0"
!define SHORTVERSION "8.1"
!define NAME "SchoolServer MainHost"
!define SHARPDEVFOLDER "..\..\..\.."
!define STOCKINPUTFOLDER "${SHARPDEVFOLDER}\SchoolServer_100\SS-Server"
!define PARENTSTOCKFOLDER "${SHARPDEVFOLDER}\SchoolServer_100"
!define MSVC2005_X86REDIST_PRODUCTCODE {A49F249F-0C91-497F-86DF-B2585E8E76B7}
!define MSVC2005_X86REDIST_PRODUCTCODE_SP1 {7299052B-02A4-4627-81F2-1818DA5D550D}
!define MSVC2005_X86REDIST_PRODUCTCODE_SP1_UP {837B34E3-7C30-493C-8F6A-2B0F04E2912C}
!define INSTALLSTATE_DEFAULT 5
!define MACRO_check_successful_install "!insertmacro check_vc_install"
!define MACRO_check_successful_install_exclusive_2005 "!insertmacro check_vc_install_exclusive_2005"
Var function_call_return
Var tested_vc_key
!macro check_vc_install install_key
DetailPrint "Copying ${install_key} to tested_vc_key"
StrCpy $tested_vc_key ${install_key}
call check_vc_install_normal
!macroend
!macro check_vc_install_exclusive_2005 install_key
StrCpy $tested_vc_key ${install_key}
call check_vc_install_exclusive_2005
!macroend
OutFile "${NAME} Lite Installer - ${SHORTVERSION}.exe"
#Sections
Section "Installation"
SetShellVarContext all
SetOutPath "$INSTDIR"
SetRebootFlag false
DetailPrint "Installing VC++ 2005"
File "${STOCKINPUTFOLDER}\bin\Debug\vcredist_x86.EXE"
ClearErrors
ExecWait "$OUTDIR\vcredist_x86.EXE /q:a /c:$\"msiexec /i vcredist.msi /qb /norestart$\" " $0 ; also can use /qn
;we will not delete the file out-rightly so that evaluation of IfErrors below is clean
IfErrors execError noError
execError:
MessageBox MB_OK|MB_ICONEXCLAMATION "First line error!"
Goto ShortEndInstall
ShortEndInstall:
MessageBox MB_OK|MB_ICONEXCLAMATION "Installation of Microsoft Visual C++ 2005 runtime libraries failed!"
Delete "$OUTDIR\vcredist_x86.EXE" ;we did not delete the file outrightly so that evaluation of IfErrors is clean
;Quit
Return
noError:
;if no error, then check the exit code (https://sourceforge.net/p/nsis/mailman/message/22965694/ [use timemachine if 404 error. Page was accessed June 26, 2017])
${If} $0 != 0
MessageBox MB_OK|MB_ICONEXCLAMATION "You did not complete the installation of the VC++ 2005 re-distributable. Installation will now abort. [Error $0]"
Goto ShortEndInstall
${EndIf}
ClearErrors
${MACRO_check_successful_install} ${MSVC2005_X86REDIST_PRODUCTCODE}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
${MACRO_check_successful_install} ${MSVC2005_X86REDIST_PRODUCTCODE_SP1}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
${MACRO_check_successful_install} ${MSVC2005_X86REDIST_PRODUCTCODE_SP1_UP}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
${MACRO_check_successful_install_exclusive_2005} ${MSVC2005_X86REDIST_PRODUCTCODE}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
${MACRO_check_successful_install_exclusive_2005} ${MSVC2005_X86REDIST_PRODUCTCODE_SP1}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
${MACRO_check_successful_install_exclusive_2005} ${MSVC2005_X86REDIST_PRODUCTCODE_SP1_UP}
${If} $function_call_return == "installed"
Goto ContinueInstallation
${Else}
DetailPrint "Quiting... [Returned value: $function_call_return]"
Goto ShortEndInstall
${EndIf}
${EndIf}
${EndIf}
${EndIf}
${EndIf}
${EndIf}
ContinueInstallation:
Delete "$OUTDIR\vcredist_x86.EXE" ;we did not delete the file outrightly so that evaluation of IfErrors is clean
CreateDirectory "$INSTDIR\idcard"
File /r "${STOCKINPUTFOLDER}\bin\Debug\idcard"
SectionEnd
Function check_vc_install_normal
DetailPrint "check_vc_install_normal: Checking installation of $tested_vc_key"
System::Call 'MSI::MsiGetProductInfo(t "$tested_vc_key", t "ProductName", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
ClearErrors
${If} $0 == 0
DetailPrint "ProductName: $1"
System::Call 'MSI::MsiGetProductInfo(t "$tested_vc_key", t "AssignmentType", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "AssignmentType: $1"
System::Call 'MSI::MsiGetProductInfo(t "$tested_vc_key", t "PackageCode", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "PackageCode: $1"
System::Call 'MSI::MsiGetProductInfo(t "$tested_vc_key", t "VersionString", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "VersionString: $1"
StrCpy $function_call_return "installed"
${Else}
DetailPrint "Not installed [$0] [from check_vc_install_normal]"
StrCpy $function_call_return "not installed"
${EndIf}
FunctionEnd
Function check_vc_install_exclusive_2005
DetailPrint "check_vc_install_exclusive_2005: Checking special vc2005 installation of $tested_vc_key"
ClearErrors
System::Call 'MSI::MsiQueryProductState(t "$tested_vc_key")i.r0'
${If} ${INSTALLSTATE_DEFAULT} = $0
StrCpy $function_call_return "installed"
${Else}
DetailPrint "Not installed [$0] [from check_vc_install_exclusive_2005]"
StrCpy $function_call_return "not installed"
${EndIf}
FunctionEnd
【问题讨论】:
-
ExecWait 之后的 $0 是多少? 0 还是其他数字?
-
@Anders 总是
0
标签: visual-c++ nsis visual-c++-2005