MSI 安装被自定义操作 DLL 中断

Posted

技术标签:

【中文标题】MSI 安装被自定义操作 DLL 中断【英文标题】:MSI installation interrupted by custom action DLL 【发布时间】:2017-12-08 15:54:38 【问题描述】:

我已使用 Visual Studio 安装项目来创建 MSI。我在 Orca 中编辑了 MSI,以便在首次打开时通过 DLL 执行自定义操作。当我运行 MSI 时,msiexec 会记录以下内容:

MSI (c) (E4:BC) [15:28:14:453]: Doing action: CustomAction1
Action 15:28:14: CustomAction1. 
Action start 15:28:14: CustomAction1.
MSI (c) (E4:BC) [15:28:14:453]: Note: 1: 2235 2:  3: ExtendedType 4: SELECT `Action`,`Type`,`Source`,`Target`, NULL, `ExtendedType` FROM `CustomAction` WHERE `Action` = 'CustomAction1' 
MSI (c) (E4:BC) [15:28:14:453]: Creating MSIHANDLE (13) of type 790542 for thread 3260
MSI (c) (E4:B4) [15:28:14:453]: Invoking remote custom action. DLL: C:\DOCUME~1\USERNA~1\LOCALS~1\Temp\MSIA3.tmp, Entrypoint: SampleFunction
MSI (c) (E4:B4) [15:28:14:453]: Closing MSIHANDLE (13) of type 790542 for thread 3260
Action ended 15:28:14: CustomAction1. Return value 3.
MSI (c) (E4:BC) [15:28:14:468]: Doing action: FatalErrorForm
Action 15:28:14: FatalErrorForm. 
Action start 15:28:14: FatalErrorForm.
MSI (c) (E4:BC) [15:28:14:468]: Note: 1: 2235 2:  3: ExtendedType 4: SELECT `Action`,`Type`,`Source`,`Target`, NULL, `ExtendedType` FROM `CustomAction` WHERE `Action` = 'FatalErrorForm' 

然后安装程序向导会显示错误消息:The installer was interrupted before MyProduct could be installed. You need to restart the installer to try again.

自定义 DLL 是用 C++ 编写的。以下是源代码:

MyCustomAction.cpp:

// MyCustomAction.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)

    return TRUE;


UINT __stdcall SampleFunction(MSIHANDLE hModule)

        //This is the function that is called by the MSI
        //It is empty because I just want to check that it can be called without interrupting the installer, then I will add the actual functionality

MyCustomAction.def:

; MyCustomAction.def
;
; defines the exported functions which will be available to the MSI engine

LIBRARY      "MyCustomAction" 
DESCRIPTION  'Custom Action DLL'

EXPORTS
    SampleFunction

我还在 DLL 的附加依赖项中引用了msi.lib。当我目前没有明确告诉它做任何事情时,为什么自定义操作会中断安装?任何帮助将不胜感激。

更新:

在 Orca 中,自定义操作位于 Binary 表中,并且是 CustomAction 表中的类型 1。自定义操作是 Immediate,在 InstallUISequence 表中发生在 IsolateComponents 之后和 WelcomeForm 之前。

【问题讨论】:

你的函数没有返回任何东西; VS 不会产生警告吗? @tkausl 没有警告。它构建成功。 那么我猜警告级别不够高。不过,该函数需要返回一些东西。 @tkausl 我也成功了return 1;,但我遇到了同样的问题。 是的,因为 MSI 想要ERROR_SUCCESS 【参考方案1】:

您应该更新您的代码和您的帖子,以表明您实际上正在返回 ERROR_SUCCESS。不管它是否解决了问题,关键是它是正确的做法。如果它不返回值,则调用序列将失败并出现错误。

您的 Dll 可能由于缺少依赖项而无法加载。如果您在代码中放置一个简单的消息框调用,您至少会看到代码是否真正开始运行。 C++ 将需要运行时支持 Dll,这些 Dll 可能已经不在系统上。

如果发现您依赖于 C++ 运行时,那么您需要在运行 MSI 之前安装它们。这就是先决条件选择的用途——它会生成一个 setup.exe 来安装依赖项,然后安装您的 MSI。

【讨论】:

我想他可以尝试 static linking 来防止任何依赖问题 - 我认为 setup dll 是少数几种在所有情况下实际上都应该是最小依赖的二进制文件之一(在大多数其他情况下,我认为静态链接是错误的)。总的来说,我认为他应该选择 WiX 而不是这样先进的东西?更大的问题是自定义操作的用途。 刚刚检查了 Visual Studio 2017 社区版(家用电脑)。我可以在项目的属性页中看到一个静态链接 MFC 的选项,但我认为完全有一个用于静态链接的选项(也适用于标准库)。我已经好几年没用过这个功能了,所以我不确定,也许社区版不允许正确的静态链接? Phil,你介意检查一下这些信息吗(webJose 的回答):cplusplus.com/forum/general/18397(“清单必须去”让我有点担心,但我希望 MFC、ATL、CRT 全部静态链接,或者更好地避免 CA dll)。 在我看来,清单注释无关紧要 - 只需使用静态链接嵌入运行时 Dll,或先运行 VC_runtime 先决条件。

以上是关于MSI 安装被自定义操作 DLL 中断的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义操作 DLL (MSI/Wix) 中获取“INSTALLED”属性?

自定义操作中的第三方 exe - installshield

WIX 自定义卸载操作失败

使用Wix在MSI中自定义操作出错时显示最终用户消息

MSI安装的数据持久性

Wix 自定义卸载操作 - 如何在 msi 删除文件之前运行