如何让NSIS在msi上等待?
问题描述:
我正在处理NSIS中的安装程序,我正在寻找一种方法来启动msi安装程序并等待安装程序完成,然后再继续。我以各种方式研究了我所能做到的一切,但没有运气。无论我尝试什么方式,msi都会启动,但随后NSI脚本会在msi安装程序完成之前立即执行(更具体地说,正如我所了解的,msi快速完成,但启动了它自己的独立安装程序exe,即NSIS脚本不会等待)。如何让NSIS在msi上等待?
代码摘录,包括我尝试注释的许多不同方法中的一些。
# Include files
!include x64.nsh
!include nsdialogs.nsh
!include LogicLib.nsh
!include MUI2.nsh
!include WinVer.nsh
!include nsDialogs_userData.nsh
!include StrFunc.nsh
!include nsDialogs_createIPaddress.nsh
!include nsProcess.nsh
!include WordFunc.nsh
!include WinMessages.nsh
!include FileFunc.nsh
Function MYSQL_SERVER_INSTALLATION
;Exec 'start /wait "msiexec.exe" /i "$INSTDIR\mysql-installer-community-5.7.13.0.msi"'
ExecWait '"msiexec.exe" /i "$INSTDIR\mysql-installer-community-5.7.13.0.msi"'
;Pop $0
;ExecDos::wait $0
#The mySQL msi opens up MySQLInstaller.exe. That's the real program to wait on.
;ExecWait '"$PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe" /s'
MSILoop:
FindProcDLL::FindProc "$INSTDIR\mysql-installer-community-5.7.13.0.msi"
StrCmp $R0 0 0 +2
MessageBox MB_OK "The number is $R0 meaning $INSTDIR\mysql-installer-community-5.7.13.0.msi is not found."
Goto MySQLInstallerLoop
StrCmp $R0 1 0 +2
MessageBox MB_OK "The number is $R0 meaning $INSTDIR\mysql-installer-community-5.7.13.0.msi is found."
Goto MSILoop
MySQLInstallerLoop:
FindProcDLL::FindProc "$PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe"
StrCmp $R0 0 0 +2
MessageBox MB_OK "The number is $R0 meaning $PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe is not found."
Goto ConfigureDatabase
StrCmp $R0 1 0 +2
MessageBox MB_OK "The number is $R0 meaning $PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe is found."
Goto MySQLInstallerLoop
; FindProcDLL::WaitProcStart "$PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe" 500
; FindProcDLL::WaitProcEnd "$PROGRAMFILES\MySQL\MySQL Installer for Windows\MySQLInstaller.exe" -1
ConfigureDatabase:
# Configure the MySQL Community
!insertmacro ConfigureMySQLDatabase
!insertmacro CreateMySQLMCSTDatabases
# Delete the MySQL Community installation
SetOutPath "$INSTDIR"
Delete /REBOOTOK "$INSTDIR\mysql-installer-community-${MYSQL_VERSION}.msi"
FunctionEnd
- 启动/等待行甚至不运行MSI文件,可能是由于语法错误。
- msi文件的ExecWait行工作并打开msi文件,但不会等待。
- 更改ExecWait到ExecDos :: Exec和在弹出$ 0和 ExecDos增加::等待$ 0作品只是罚款的exe安装程序,我需要 安装,但没有为MSI安装程序。
- 如果我尝试运行MSI文件启动的MySQLInstaller.exe上的ExecWait,我得到一个对话框错误信息,通知该exe的两个副本不能同时运行(我直接在此执行它并且msi也在执行它)。
- 我试图寻找一个简单的等待而不是执行的命令,并等待,但我找不到一个。我确实找到了一个有希望的创建循环的方法,该循环查找正在运行的程序,并在完成时退出,但只在两个循环中立即返回0。
- 我试过了WaitProcStart和WaitProcEnd,但是这些都没有做任何事情。不幸的是,FindProcDLL的NSIS插件页面表示,从NSIS 2.46开始,插件甚至不再工作,所以我可能做出了徒劳的尝试(对于循环来说也是一样)。
- 我试过找到一个进程的nsProcess版本,因为这看起来是FindProcDLL的替代品,但这也不起作用。
仅供参考,我都开发并提供一个Windows 10的64位机器上,我使用NSIS V3.01。
答
Exec 'start /wait ...'
永远不会工作,即使您将其更改为ExecWait
它仍然无法工作,因为start
是Windows NT系统中cmd.exe内部的命令。
只是为了设置事项,ExecWait
总是等待,但它只是等待子进程而不是孙子。有可能use a job object等待孙子们,但MSI使用的不是孙子的Windows服务,所以工作对象可能不会帮助你。
任何类型的查找过程插件都不起作用,因为.MSI文件不是PE可执行文件,它只是一个数据库,可能还有一些CAB压缩文件。
正确的解决方案是使用ExecWait
但你要问MySQL的人,其开关传递给MSIEXEC和/或它们的安装程序.EXE ...