Installation 无法从自定义操作浏览/引用.net类库dll文件(它是产品部署的一部分,并且依赖于.net exe文件)
我正在一个基本MSI(installshield 2014)项目中创建一个新的自定义操作。我必须在托管.Net程序集中调用公共方法,该程序集作为产品部署的一部分进行部署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时看到
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用于呼叫他们,我为我的问题添加了更清晰的内容,并添加了一个答案,在此基础上我能够解决我的问题。它终于变了