无法从自定义操作 browse/refer .net class 库 dll 文件(它是产品部署的一部分和 .Net exe 文件的依赖项)
Unable to browse/refer a .net class library dll file (which is part of product deployment and dependency of an .Net exe file) from custom action
我正在基本 MSI (installshield 2014) 项目中创建新的自定义操作。我必须在作为产品部署的一部分部署的托管 .Net 程序集 abc.dll
中调用 public 方法。 abc.dll
是名为 component1
的组件的一部分,该组件是设置设计中功能 feature1
的一部分。
当我尝试在自定义操作创建向导中引用该程序集时,我提到它的 Location
为 Installed with the product
。但是在自定义操作创建向导的 Action Parameters
步骤中,当我尝试在部署路径中浏览 abc.dll
时,我没有看到它:
虽然我在组件中浏览它时能够看到 abc.dll
,如下面的快照所示。 abc.dll
作为 component1
的一部分存在,它部署在产品的 %programfiles%
路径中。
另一方面,我可以在自定义操作创建向导中看到一个 pqr.exe
文件(作为另一个组件 component2
的一部分部署),如下面的快照所示:
任何人都可以指导我为什么会发生这种情况吗?
我假设 InstallShield 正在验证这些二进制文件是否可以作为自定义操作调用。可执行文件可以 运行 作为自定义操作,因此它会显示出来。 Dll 不能被任意调用,除非它导出具有所需签名的入口点。 Windows 安装程序不支持调用托管代码自定义操作,因此可能 InstallShield 提供了一个 C++ shim 来调用(Visual Studio 安装程序项目也是如此)。否则 C++ Dll 需要有这个签名:
UINT__stdcall CustomActionEntryPoint(MSIHANDLE hInstall)
此处示例:
https://www.simple-talk.com/dotnet/visual-studio/visual-studio-setup-projects-and-custom-actions/
https://www.codeproject.com/Articles/570751/DevMSI-An-Example-Cplusplus-MSI-Wix-Deferred-Custo
正如我所说,您的 IS 版本可能支持在调用 Dll 的其他一些描述下调用托管代码 Dll(与 "calling a standard Windows Installer custom action" 之类的描述相反)。
我终于找到了我的解决方案。这一切都归结为 Installshield 如何处理 .Net 程序集及其依赖项的打包。
Installshield 引用 .Net exe 及其依赖项的方式的区别:
每当您添加主项目输出时,例如pqr.exe
在我的例子中,它被添加到一个组件中。当您浏览您的组件时,您将根据 installshield 环境的标准已知变量在 Link To
列下看到 exe 的源路径,例如[InstallDir]\ComponentName\
等
现在,当 installshield 必须创建用于部署 .Net 程序集的 MSI 包时,例如pqr.exe
在我的例子中,它还尝试打包其依赖项以进行部署。在我的例子中 prq.exe
取决于 abc.dll
。但需要注意的是,installshield 不会在其自己的 *.ISM
安装程序项目文件中静态维护 .Net 程序集的依赖项列表。
所以 abc.dll
也显示在组件中,但它的路径作为完全限定路径出现在正在构建 ISM 文件的磁盘上,例如D:\mywork\MSIProject\
。这是因为 abc.dll
实际上不是 ISM 安装程序项目文件的一部分。事实上,我在文本编辑器中打开了 ISM 文件的 xml 格式并尝试搜索 abc.dll
并且它根本不存在。因此 abc.dll
不作为要在 ISM 安装程序定义文件中部署的程序集存在。但只有在构建 ISM 文件时,它才会尝试将所有依赖项与 *.exe 文件一起打包。
所有依赖项都应存在于 *.exe 文件所在的同一根目录中,否则 installshield 将无法打包它们。
installshield 打包 .Net exe 及其依赖项的方式的区别:
另一个需要注意的不同点是,如果您从正在构建 ISM 文件的磁盘路径中删除 pqr.exe
,那么 ISM 文件将无法构建,但是如果您删除 abc.dll
(这是不是 ISM 定义文件的物理部分,因为它只是一个 reference/dependency),那么 ISM 文件仍将成功构建。
installshield 中的自定义操作如何引用 .Net exe 及其依赖项之间的区别:
就我的实际问题而言,您只能在自定义操作中直接引用那些作为组件一部分的程序集。您不能仅引用逻辑上看起来像组件一部分的程序集(因为它们是依赖项),但实际上它们显示在那里只是因为它们是托管 .Net exe 文件的依赖项。
我正在基本 MSI (installshield 2014) 项目中创建新的自定义操作。我必须在作为产品部署的一部分部署的托管 .Net 程序集 abc.dll
中调用 public 方法。 abc.dll
是名为 component1
的组件的一部分,该组件是设置设计中功能 feature1
的一部分。
当我尝试在自定义操作创建向导中引用该程序集时,我提到它的 Location
为 Installed with the product
。但是在自定义操作创建向导的 Action Parameters
步骤中,当我尝试在部署路径中浏览 abc.dll
时,我没有看到它:
虽然我在组件中浏览它时能够看到 abc.dll
,如下面的快照所示。 abc.dll
作为 component1
的一部分存在,它部署在产品的 %programfiles%
路径中。
另一方面,我可以在自定义操作创建向导中看到一个 pqr.exe
文件(作为另一个组件 component2
的一部分部署),如下面的快照所示:
任何人都可以指导我为什么会发生这种情况吗?
我假设 InstallShield 正在验证这些二进制文件是否可以作为自定义操作调用。可执行文件可以 运行 作为自定义操作,因此它会显示出来。 Dll 不能被任意调用,除非它导出具有所需签名的入口点。 Windows 安装程序不支持调用托管代码自定义操作,因此可能 InstallShield 提供了一个 C++ shim 来调用(Visual Studio 安装程序项目也是如此)。否则 C++ Dll 需要有这个签名:
UINT__stdcall CustomActionEntryPoint(MSIHANDLE hInstall)
此处示例:
https://www.simple-talk.com/dotnet/visual-studio/visual-studio-setup-projects-and-custom-actions/
https://www.codeproject.com/Articles/570751/DevMSI-An-Example-Cplusplus-MSI-Wix-Deferred-Custo
正如我所说,您的 IS 版本可能支持在调用 Dll 的其他一些描述下调用托管代码 Dll(与 "calling a standard Windows Installer custom action" 之类的描述相反)。
我终于找到了我的解决方案。这一切都归结为 Installshield 如何处理 .Net 程序集及其依赖项的打包。
Installshield 引用 .Net exe 及其依赖项的方式的区别:
每当您添加主项目输出时,例如pqr.exe
在我的例子中,它被添加到一个组件中。当您浏览您的组件时,您将根据 installshield 环境的标准已知变量在 Link To
列下看到 exe 的源路径,例如[InstallDir]\ComponentName\
等
现在,当 installshield 必须创建用于部署 .Net 程序集的 MSI 包时,例如pqr.exe
在我的例子中,它还尝试打包其依赖项以进行部署。在我的例子中 prq.exe
取决于 abc.dll
。但需要注意的是,installshield 不会在其自己的 *.ISM
安装程序项目文件中静态维护 .Net 程序集的依赖项列表。
所以 abc.dll
也显示在组件中,但它的路径作为完全限定路径出现在正在构建 ISM 文件的磁盘上,例如D:\mywork\MSIProject\
。这是因为 abc.dll
实际上不是 ISM 安装程序项目文件的一部分。事实上,我在文本编辑器中打开了 ISM 文件的 xml 格式并尝试搜索 abc.dll
并且它根本不存在。因此 abc.dll
不作为要在 ISM 安装程序定义文件中部署的程序集存在。但只有在构建 ISM 文件时,它才会尝试将所有依赖项与 *.exe 文件一起打包。
所有依赖项都应存在于 *.exe 文件所在的同一根目录中,否则 installshield 将无法打包它们。
installshield 打包 .Net exe 及其依赖项的方式的区别:
另一个需要注意的不同点是,如果您从正在构建 ISM 文件的磁盘路径中删除 pqr.exe
,那么 ISM 文件将无法构建,但是如果您删除 abc.dll
(这是不是 ISM 定义文件的物理部分,因为它只是一个 reference/dependency),那么 ISM 文件仍将成功构建。
installshield 中的自定义操作如何引用 .Net exe 及其依赖项之间的区别:
就我的实际问题而言,您只能在自定义操作中直接引用那些作为组件一部分的程序集。您不能仅引用逻辑上看起来像组件一部分的程序集(因为它们是依赖项),但实际上它们显示在那里只是因为它们是托管 .Net exe 文件的依赖项。