简体   繁体   中英

How do I get NSIS to wait on an msi?

I'm working on an installer in NSIS and I'm looking for a way to start an msi installer and wait for that installer to finish before proceeding. I've researched everything I can on various ways to do this with no luck. Regardless of any manner I try, the msi starts up but then the NSIS script proceeds immediately before the msi installer is finished (more specifically, as I've learned, the msi finishes quickly but starts up its own separate installer exe that the NSIS script won't wait on).

Code excerpt, including a few of the many different methodologies I've tried commented out.

# 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
  • The start /wait line doesn't even run the msi file, possibly due to errors in syntax.
  • The ExecWait line for the msi file works and opens the msi file, but doesn't wait.
  • Changing ExecWait to ExecDos::exec and adding in the Pop $0 and ExecDos::wait $0 works just fine for the exe installers I need to install but not for the msi installer.
  • If I try and run ExecWait on the MySQLInstaller.exe that the msi file starts up, I get a dialog error box informing that two copies of this exe can't run at the same time (I'm executing it directly here and the msi is also executing it).
  • I tried looking for a command that simply waits instead of executes and waits but I couldn't find one. I did find someone's promising idea of making a loop that looks for the program running and exits out when it's done existing, but that only returns 0 immediately in both loops.
  • I've tried the WaitProcStart and WaitProcEnd but those don't do anything. Unfortunately, the NSIS plugin page for FindProcDLL says that as of NSIS 2.46 the plug in doesn't even work anymore, so I was probably making a futile attempt (same for the loops).
  • I tried the nsProcess version of finding a process because that looked to be the replacement for FindProcDLL, but that doesn't work either.

For reference, I am both developing and delivering on a Windows 10 64-bit machine and I'm using NSIS v3.01.

Exec 'start /wait ...' is never going to work and even if you change it to ExecWait it is still not going to work because start is an internal command inside cmd.exe on Windows NT systems.

Just to set things straight, ExecWait always waits but it only waits for the child process, not grandchildren . It is possible to use a job object to wait for grandchildren but MSI uses a Windows service that is not a grandchild so a job object is probably not going to help you here.

Any type of find process plug-in is not going to work because a .MSI file is not a PE executable, it is just a database and maybe some CAB compressed files.

The correct solution is to use ExecWait but you have to ask the MySQL people which switches to pass to MSIExec and/or their installer .EXE...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM