如何从msi安装中检索详细结果

时间:2016-07-14 01:22:01

标签: c++ wix windows-installer

我有一个由Wix工具集创建的.msi文件,用于安装5个驱动程序。我有一个安装应用程序,通过使用msiexec.exe命令通过CreateProcess启动.msi,并提供UI。目前,我的要求是获得安装的详细结果 - 哪些驱动程序安装成功,哪些失败。由于我可以获得CreateProcess的结果,如何从安装中检索详细结果?非常感谢您能提供有关此问题的一些信息。

我使用difx:Driver标志创建了.msi文件,如下所示:

<difx:Driver AddRemovePrograms="no" DeleteFiles="no" ForceInstall="no" Legacy="no" PlugAndPlayPrompt="no" />

4 个答案:

答案 0 :(得分:1)

基于MSI的设置是事务性的。它要么全部工作要么全部失败并将系统回滚到之前的状态。看起来你已经做出了选择,打败了这个范例,部分成功地让一些驱动程序安装而其他驱动程序没有安装。

您还看到已禁止安装程序的UI,因此无法找到错误信息。

我有两条建议:

  1. 不要使用CreateProcess()和&#34; fire and forget&#34;模型。将MsiSetExternalUIRecord与此模型一起使用:
  2. https://msdn.microsoft.com/en-us/library/windows/desktop/bb309215(v=vs.85).aspx

    那里也有C#p / invoke等价物。如果您不想显示所有用户界面,则只需收集错误消息并将其显示给用户(如果这是目标)。这是获取实际错误消息的唯一可靠方法。这是您拥有UI并仅收集您认为重要的消息的受支持方式。

    1. 允许失败的驱动程序安装使整个安装失败并将其全部回滚。实际上可能就是这样。如果安装部分成功并且未安装四个驱动程序,那么计划是什么?您无法再次运行MSI,因为它将进入维修/维护模式。如果用户需要修复某些内容并再次进行安装,则无论如何都需要卸载产品。

答案 1 :(得分:0)

您可以使用/ L * V参数检索详细安装日志:

msiexec /i "C:\MyPackage\Example.msi" /L*V "C:\log\example.log"

您可以阅读更多here

一般结构是:

msiexec.exe [/i][/x] <path_to_package> [/L{i|w|e|a|r|u|c|m|o|p|v|x+|!|*}][/log] 

/L - enable logging i - include status messages w - include non-fatal warnings e - include all error messages a - mention when an action is started r - include action-specific records u - include user requests c - include the initial UI parameters m - include out-of-memory or fatal exit information o - include out-of-disk-space messages p - include terminal properties v - verbose output x - include extra debugging information + - append to an existing log file ! - flush each line to the log * - log all information, except for v and x options

答案 2 :(得分:0)

另一个更简单的方法是将一个小的C#自定义操作写入计算机上的check if the drivers are installed,而不是解析日志。

您需要将安装过程结束时的自定义操作安排为延迟(非直接)。

答案 3 :(得分:0)

您可以生成一个日志(如Harsh所建议的),或者您可以创建一个自定义操作(如果您使用他建议的方法,则按照Bogdan建议延迟)或在InstallFinalize之后排序(如果您有其他方法不能不需要提升,但该自定义操作可能需要使用某种IPC来将它找到的内容传达给您的程序。

IPC的一种可能性可能是您的自定义操作中的MsiProcessMessage函数,其中您可以在应用程序中接收INSTALLMESSAGE_INFO消息类型(您发送的内容也将显示在日志中),但这需要使用MsiSetExternalUIRecord函数,需要用该页面的安装和配置功能部分替换你的CreateProcess调用msiexec。

或者,如果您不需要编写自定义操作,则可以更轻松地使用MsiGetFeatureState or MsiGetComponentState拨打MsiOpenProduct,假设这样可以为您提供详细信息。< / p>