繁体   English   中英

如何让NSIS等待MSI?

[英]How do I get NSIS to wait on an msi?

我正在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
  • start / wait行甚至没有运行msi文件,这可能是由于语法错误造成的。
  • msi文件的ExecWait行可以工作并打开msi文件,但不等待。
  • 将ExecWait更改为ExecDos :: exec并添加Pop $ 0和ExecDos :: wait $ 0对于需要安装的exe安装程序很好,但对于msi安装程序却没有问题。
  • 如果我尝试在运行MySQLInstaller.exe的ExecWait上运行msi文件,则会收到一个对话框错误消息,通知该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内部的内部命令。

只是为了ExecWaitExecWait总是等待,但只等待子进程,而不是孙子进程。 可以使用作业对象来等待孙子,但是MSI使用的不是Windows的Windows服务,因此作业对象可能不会在这里为您提供帮助。

任何类型的查找过程插件都无法使用,因为.MSI文件不是PE可执行文件,它只是一个数据库,也许还有一些CAB压缩文件。

正确的解决方案是使用ExecWait但是您必须询问要切换到MSIExec和/或其安装程序.EXE的MySQL人员。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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