我有一个基本的 MSI InstallShield 安装,其中包含从二进制表运行的托管 EXE 自定义操作。我尝试了一个简单的测试,它只运行一个控制台并且工作正常。当我向 EXE 添加 .DLL 程序集引用时,它找不到 DLL。如何让 InstallShield 知道这个引用的程序集,以便它可以使用 EXE 加载它?
4 回答
自定义操作仅以临时名称将单个文件提取到临时位置。要使对 .dll 的依赖项起作用,它们都需要被提取,并且至少 .dll 必须具有预期的名称。[SUPPORTDIR]\your.exe
通常,通过将两者都添加到“设置文件”并引用自定义操作,最容易做到这一点。
好吧,我将在 Installshield 2014 中添加有关它今天如何工作的详细信息。对于其他 installshield 版本,其他答案可能同样正确。我可以看到迈克尔的回答是从 2012 年开始的,从那时起很多事情都发生了变化。让我们来看看。
.Net 程序集可以有两种类型的依赖项:
- 托管(用 C# 或 VB.Net 语言编写。OP 有这种特殊情况)
- 非托管或本机(例如,通过 p/invoke 调用的 C++ dll)。您不会在 C# 项目中引用此类程序集,但它们会在运行时使用
DllImport
属性和定义明确的程序集搜索机制加载。
让我们了解 OP 的问题,即依赖托管程序集的情况:
仅供大家参考,installshield 内部有一个自己的数据库。因此,当您添加调用托管程序集中存在的方法的自定义操作(在您的 installshield 基本 MSI 项目中)时,自定义操作的所有属性都将作为记录放入ISClrWrap
内部数据库表中,如下所示:
现在 installshield 不提供任何用户界面或直接机制,我们可以在其中定义托管程序集的依赖项(您在 Visual Studio 的 C# 项目中作为引用添加的那些)。但是您可以更新此数据库表以反映相同的情况。您需要为该表中的每个新依赖项添加一条记录。对于名称列,您应该选择Dependency0
第一个依赖项,Dependency1
第二个依赖项,依此类推。请看下面的快照,了解我在按下顶部的新按钮以添加新记录后是如何完成的:
添加所有托管依赖项程序集后,表开始如下所示:
而已。你从这里完成。剩下的留给 installshield。现在存在的方法MyManagedAssembly.dll
将能够调用存在于安装过程中MyManagedDependencyAssembly1.dll
或MyManagedDependencyAssembly2.dll
安装过程中的方法。
备注:
- 您不必将托管依赖程序集添加到支持文件(其路径由
[SUPPORTDIR]
属性表示)。installshield 如何在安装过程中管理托管依赖程序集的复制是其内部实现细节。 - 您的 C# 项目(在自定义操作中使用)对核心 .NET 程序集的依赖项,这些程序集是 .NET 框架 FCL 例如等的一部分
System.dll
,Systen.Core.dll
不需要添加到此表中。它们在 InstallShield 加载 CLR 以执行托管代码时默认加载。
我找不到一种体面的方式来使用 .Net 自定义操作,让我可以做我想做的事情。我最终使用 WiX 的 DTF(部署工具基础)部分来创建程序集,并且效果很好。
请将您的 DLL 作为依赖项添加到“isclrwrap”二进制表中。您可以从直接编辑器中找到该二进制表。这将解决您的问题。