自定义操作返回错误时中断安装

时间:2019-02-28 11:50:31

标签: wix windows-installer custom-action

我有一种方法可以验证.dll中的密码,并且在失败时应返回错误代码。它具有以下原型:

#define DllExport __declspec( dllexport )
extern "C" DllExport UINT TestPassword(MSIHANDLE hInstall);

我希望当此方法返回错误代码(如ERROR_INSTALL_USEREXIT = 1602)时,整个安装过程将终止(不会执行此操作之后的其他自定义操作),但是不会。

此外,在Wix中,我有以下片段:

 <CustomAction Id='TestPassword' BinaryKey='TestPassword' DllEntry='TestPassword' Execute='immediate'
              Return='check'/>

<Binary Id='TestPassword' SourceFile='DummyDll.dll'/>

1 个答案:

答案 0 :(得分:2)

  

更新:一些有用的链接。

     

疑似原因:

在顶部列出一些建议。

  • 1错误的C ++自定义操作代码配置,通常忘记创建 CA.def 文件来定义dll导出。我也总是使用__stdcall(MSI是个老女孩)。
  • 2 WiX标记中自定义操作dll的路径错误(MSI中无效的dll)。
  • 3) 忘记启用对WiX标记(* .WXS)中的错误代码的检查,那么CA不会结束设置。在您的情况下 (Return='check')
  • 4忘记按安装顺序插入自定义操作。
  • 还有更多,目前无法想到。以后可能会添加...想到的是位问题(x86 / 64)...
  • 文件和运行时依赖项是典型的失败原因。
    • 尝试静态链接
    • 部署DLL应该至少具有依赖性,因为它们需要在任何系统上以任何语言,任何状态,在任何OS版本上运行,等等。
    • 真正推荐使用静态链接并且始终是正确选择的少数情况之一。
  

注意 :要避免在安装程序中获得许可?我建议您将许可证验证放到您的应用程序中,而不是在安装程序中。这里   关于此事有一些想法:   Installer with Online Registration for Windows Application推荐阅读)。


技术问题:

FileName.def :我不是C ++专家,但是您的项目中是否有 FileName.def 文件要声明dll的导出功能?如果不是,请添加一个(下面的步骤/过程)。确保其格式正确(通过Visual Studio添加,我认为它是没有BOM的UTF8)。编译并使用Dependency Walker检查所有导出是否正确:

MSI DLL

验证MSI文件DLL :您应检查已编译的MSI,以确认其中具有正确的DLL,并具有正确的导出功能。因此;验证DLL是否已安全地放入MSI的Binary表中:

  1. 使用 Orca or equivalent)打开您编译的MSI
  2. 二进制表,双击数据列作为您的DLL条目。
  3. 选择“ 将二进制文件写入文件名”,然后保存到桌面(或其他位置)。
  4. 使用Dependency Walker(depends.exe)来验证您是否具有有效的DLL,如上图所示。 常见问题是您根本看不到任何导出MyImmediateCAMyTestFailMyTestSuccessetc...)。
  5. 在文件属性中验证文件-产品版本

错误处理 :可以设置自定义操作来抑制错误。设置了“返回属性”后,您的标记看起来正确无误: (Return='check') 。您的摘要:

<CustomAction Id='TestPassword' BinaryKey='TestPassword' 
              DllEntry='TestPassword' Execute='immediate' Return='check'/>

测序 :还要检查您的测序是否正确。您总共需要指向二进制表DLL,声明自定义操作,然后将其插入正确的序列中。模拟WiX标记:

<!--<Binary Id="CustomActions" SourceFile="$(var.TestDll.TargetPath)" />-->
<Binary Id="CustomActions" SourceFile="C:\TestDll.dll" />

<CustomAction Id="MyTestFail" BinaryKey="CustomActions" DllEntry="MyTestFail"/>
<CustomAction Id="MyTestSuccess" BinaryKey="CustomActions" DllEntry="MyTestSuccess"/>

<InstallExecuteSequence>
  <Custom Action="MyTestSuccess" After="CostFinalize" />
  <Custom Action="MyTestFail" After="MyTestSuccess" />
</InstallExecuteSequence>

C ++ DLL :以及实际的C ++ DLL本身(请记住 *.def 文件)。来自MSI API Custom Action Security的底部代码段中的代码段:

Visual Studio 2017 的建议步骤:

  1. 创建新的VC + DLL项目-动态链接库(DLL)。
  2. 将以下代码转储到主 *.cpp 文件中(避免使用 dllmain.cpp )。
  3. 添加* .def文件!
    • Right Click Source Files => Add => New Item... => {{ 1}} => Code =>任何名称都应...(仅允许一个def文件)
    • 添加您的导出函数名称:

模型:

Module-Definition File (.def)

关闭并重新打开文件以验证是否存在任何格式错误。如果出现警告,请选择修复。我认为没有BOM的UTF8

LIBRARY

EXPORTS
     MyTestFail
     MyTestSuccess
     MyImmediateCA