如何让NSIS等待msi?

时间:2017-08-09 19:43:10

标签: windows windows-installer wait nsis msiexec

我正在使用NSIS中的安装程序,我正在寻找启动msi安装程序的方法,并等待该安装程序完成后再继续。我已经用各种方法研究了我能做到的一切,没有运气。无论我尝试何种方式,msi都会启动,但NSIS脚本会在msi安装程序完成之前立即进行(更具体地说,正如我已经了解到的那样,msi快速完成但启动了自己独立的安装程序exe, NSIS脚本不会等待。

代码摘录,包括我尝试过的许多不同方法中的一些。

# 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并添加Pop $ 0和 ExecDos :: wait $ 0适用于我需要的exe安装程序 安装但不适用于msi安装程序。
  • 如果我尝试在msIn文件启动的MySQLInstaller.exe上运行ExecWait,我会收到一个对话框错误框,告知该exe的两个副本不能同时运行(我是在这里直接执行它,msi也在执行它。)
  • 我试着寻找一个只是等待而不是执行等待的命令,但我找不到。我确实找到了一个有希望的想法,即创建一个循环来查找正在运行的程序,并在它完成时退出,但只在两个循环中立即返回0。
  • 我已经尝试过WaitProcStart和WaitProcEnd,但那些人什么都不做。不幸的是,FindProcDLL的NSIS插件页面表示,从NSIS 2.46开始,插件甚至不再工作了,所以我可能做了徒劳的尝试(对于循环也一样)。
  • 我尝试了查找进程的nsProcess版本,因为它看起来是FindProcDLL的替代品,但这也不起作用。

作为参考,我在Windows 10 64位计算机上开发和交付,我使用的是NSIS v3.01。

1 个答案:

答案 0 :(得分:0)

Exec 'start /wait ...'永远无法正常工作,即使您将其更改为ExecWait,它仍无法正常工作,因为start是Windows NT系统上cmd.exe内部的内部命令

为了做好准备,ExecWait总是等待,但它只等待子进程,而不是孙子。 use a job object可以等待孙子孙女,但MSI使用不是孙子的Windows服务,因此工作对象可能无法帮助你。

任何类型的查找进程插件都不会起作用,因为.MSI文件不是PE可执行文件,它只是一个数据库,可能是一些CAB压缩文件。

正确的解决方案是使用ExecWait,但你必须要求MySQL人员将哪些开关传递给MSIExec和/或他们的安装程序.EXE ......