Installation 无法从自定义操作浏览/引用.net类库dll文件(它是产品部署的一部分,并且依赖于.net exe文件)

Installation 无法从自定义操作浏览/引用.net类库dll文件(它是产品部署的一部分,并且依赖于.net exe文件),installation,custom-action,installshield-2014,Installation,Custom Action,Installshield 2014,我正在一个基本MSI(installshield 2014)项目中创建一个新的自定义操作。我必须在托管.Net程序集中调用公共方法,该程序集作为产品部署的一部分进行部署abc.dll是名为component1的组件的一部分,该组件是设置设计中功能feature1的一部分 当我试图在“自定义操作创建向导”中引用该程序集时,我将其位置提到与产品一起安装的。但是在自定义操作创建向导中的操作参数步骤中,当我尝试在部署路径上浏览abc.dll时,我没有看到它: 尽管我可以在组件中浏览abc.dll时看到

我正在一个基本MSI(installshield 2014)项目中创建一个新的自定义操作。我必须在托管.Net程序集中调用公共方法,该程序集作为产品部署的一部分进行部署
abc.dll
是名为
component1
的组件的一部分,该组件是设置设计中功能
feature1
的一部分

当我试图在“自定义操作创建向导”中引用该程序集时,我将其
位置提到与产品一起安装的
。但是在自定义操作创建向导中的
操作参数
步骤中,当我尝试在部署路径上浏览
abc.dll
时,我没有看到它:

尽管我可以在组件中浏览abc.dll时看到它,如下面的快照所示。
abc.dll
作为
component1
的一部分存在,该组件部署在产品的
%programfiles%
路径中

另一方面,我可以在自定义操作创建向导中看到一个
pqr.exe
文件(作为另一个组件
component2
的一部分部署),如下快照所示:


有人能告诉我为什么会发生这种情况吗?

我假设InstallShield正在验证这些二进制文件是否可以作为自定义操作调用。可执行文件可以作为自定义操作运行,因此它会显示出来。Dll不能被任意调用,除非它导出具有所需签名的入口点。没有Windows安装程序的本地支持来调用托管代码自定义操作,所以可能安装掩护提供了一个C++ SHIM来调用(如VisualStudio安装程序项目)。否则C++ DLL需要有这个签名:

UINT_uustdcall CustomActionEntryPoint(MSIHANDLE hInstall)

示例如下:


正如我所说,您的IS版本可能支持在调用DLL的其他描述下调用托管代码DLL(与“调用标准Windows Installer自定义操作”相反)

我终于找到了解决问题的办法。这一切归结为Installshield如何处理.Net程序集及其依赖项的打包

Installshield引用.Net exe及其依赖项的方式之间的差异

在我的例子中,无论何时添加主项目输出,例如
pqr.exe
,它都会被添加到组件中。当您浏览组件时,您将在链接到installshield环境的标准已知变量的
列下看到exe的源路径,例如
[InstallDir]\ComponentName\

现在,当installshield必须创建用于部署.Net程序集的MSI包时,例如在我的示例中,它还尝试打包其依赖项以进行部署。在我的例子中,
prq.exe
取决于
abc.dll
。但需要注意的是,installshield不会在自己的
*.ISM
安装程序项目文件中静态维护.Net程序集的依赖项列表

因此,组件中也显示了
abc.dll
,但它的路径在生成ISM文件的磁盘上是完全限定的路径,例如
D:\mywork\MSIProject\
。这是因为
abc.dll
实际上不是ISM insataller项目文件的一部分。事实上,我在一个文本编辑器中打开了ISM文件的xml格式,并试图搜索
abc.dll
,但它根本不存在。因此,
abc.dll
不作为要部署在ISM安装程序定义文件中的程序集出现。但只有在构建ISM文件时,它才会尝试将所有依赖项与*.exe文件一起打包

所有依赖项都应存在于存在*.exe文件的同一根目录中,否则installshield将无法对其进行打包

installshield打包.Net exe及其依赖项的方式之间的差异

另一个需要注意的不同点是,如果从生成ISM文件的磁盘路径中删除
pqr.exe
,则ISM文件将无法生成,但如果删除
abc.dll
(它不是ISM定义文件的物理部分,因为它只是一个引用/依赖项),则ISM文件仍将成功生成

installshield中自定义操作引用.Net exe及其依赖项的方式之间的差异


就我的实际问题而言,您只能直接引用自定义操作中属于组件一部分的那些程序集。您不能引用逻辑上看起来只是组件一部分的程序集(因为它们是依赖项),但实际上它们显示在那里只是因为它们是托管.Net exe文件的依赖项。

可以使用一些公共方法创建一个简单的C#dll文件,将其放在磁盘上并在自定义操作中引用它。dll存储在二进制表中,您可以将其用于自定义操作。这里我指的dll是一个简单的类库项目(没有
main
方法)。所以,为什么存储在二进制表中的dll文件不同于安装在%programfiles%目录中的组件的dll文件呢。我应该能够调用托管dll文件中的公共方法(没有
main
方法),即使它是已部署组件的一部分。我在这里遗漏了什么吗?InstallShield中可能支持包装对托管代码自定义操作的调用,就像Visual Studio中一样,但对于直接调用托管代码CA,没有本机支持。这就是为什么,例如,有DTF用于呼叫他们,我为我的问题添加了更清晰的内容,并添加了一个答案,在此基础上我能够解决我的问题。它终于变了