将程序集部署为 .Net Framework 的一部分
Deploy assembly as part of .Net Framework
我有一个针对 .NETFramework 4.0(具有强名称)的程序集 (MYASM.dll)
我想在目标机器上以它是 .NETFramework(或整个系统认为是)的一部分的方式部署这个程序集。
我的意思是:
- .NET runtime see it at it sees System.dll(无需本地部署或提供参考路径)
- 当我执行
<Reference Include="MYASM" />
时,MSBuild 会看到它而无需提示路径
- 用户可以在 Visual Studio 中创建
Add reference
并且在没有 strong/full 名称的情况下引入 <Reference Include="MYASM" />
我已经通过将其添加到 GAC 解决了 1.(显然还有 2.)。但这显然是不够的。
我已经部分解决了 3. 通过将我的程序集放在一个特殊的文件夹中 ([INSTALLFOLDER]\lib
) 并设置 registryKey HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\MyAssemblies
然后我可以添加引用,但我得到:
<Reference Include="MYASM, Version=1.1, Culture=neutral, ..." />
在我的 csproj 中,而不是我想要的 <Reference Include="MYASM" />
。
使用第二种方法,如果我手动编辑 csproj,一切正常,但我不能要求我的用户这样做。
我应该在这里做什么?
[编辑] 显然我有自己的 MSI 并不明显。但是,是的,我有。我不会用魔杖控制用户的机器
如果您有 MYASM.dll 的源代码,那么我更愿意为您的消费应用程序添加一个项目引用。这样做时,Visual Studio 将为所有引用的项目创建一个 GUID。
不,您已经尽力了。实际上,VS 如何将部分程序集名称放入项目文件中并不是那么明显。这不是 public 代码,不能被篡改。很确定它没有使用白名单,也无法关注参考程序集位置。
最有可能的细节是程序集的 PublicKeyToken。框架程序集始终具有完全相同的值,b77a5c561934e089。它的值甚至在 CLI 规范 (Ecma-335) 中有规定。接下来很可能是签名证书,将程序集标识为 Microsoft 拥有。然而,两者都存在完全相同的问题,您无法获得强名称或签署程序集所需的私钥。它们被锁在雷德蒙德的一个保险库中,只有受信任的构建工程师才能访问它们。
您还忽略了另一个讨厌的小细节,您对 DLL Hell 还不够害怕。冷酷的事实是,如果您 曾经 在另一台不受您控制的机器上公开 GAC 中的程序集,那么您将永远无法再次更改它。您不能再修改程序集的 public 界面。无法添加新的 public 方法或类型,无法修改方法的参数和 return 类型,无法添加枚举成员,等等。更苛刻的是,微软担心的是,是你也不能真正改变私人和内部成员。程序员有使用反射来四处寻找的诀窍,这是一种极好的错误修复工具。但至少你可以告诉他们 "don't do that!".
进行此类修改需要 增加 [AssemblyVersion]。现在你得到了一种不同类型的 DLL 地狱,机器可能没有被你的安装程序更新。或者更糟的是,一个解决方案使用具有不同引用的项目。 Microsoft 必须通过修改 CLR 来解决框架程序集的这个问题。自动将旧版本转发到新版本。使用为 .NET 2.0 构建的程序集的基本原因可以用于 .NET 4.x 项目。您无法为自己的 DLL 获取此类服务。
"Don't do it" 是唯一的好建议,但我可以向任何人推荐进入 DLL 地狱的麻烦是一个了不起的学习经验。地狱只有经历过才会害怕。
最好的建议是发布一个 Nuget 包。他们做的恰恰相反,从未部署在 GAC 中,版本号变化非常快。但在程序员需要时始终可用。
有几种方法...
1) 是为您的目标框架创建一个新的设置并将其打包。您可以将其打包并使用域控制器进行部署。当您的用户登录域时将更新软件包,这样您就可以将软件部署到特定用户,或者 user groups. Depending on your infrastructure 您将拥有一个可以使用的软件管理基础架构(包括 2 个链接) .
2) 如果您的目标是开发人员,请创建一个 NuGet 包。如果您的组织托管您自己的 NuGet 服务器,则限制分发。将包源添加到 Visual studio 打开选项页面,在搜索字段中键入 NuGet 并设置 URL/ UNC 路径。
3) 使用 OneClick 部署,这允许您让应用程序下载更新的 dll 并将它们安装在机器上。它需要一个代码签名证书,但你可能无论如何都要签署你的代码(如果你这样做,对反病毒工具来说更好)。
现在链接您的 MyAsam.dll 将由应用程序链接定义或 IoC 容器完成。基本上,如果它找到 dll 并且没有定义版本,它将采用它找到的第一个我认为顺序是 1 AppFolder、2 GAC、3 Path,不确定。此 "take what you find" 通常称为 "DLL-Hell",NuGet 和 OneClick 解决方案在这方面效果最好,因为您将始终获得适用于应用程序的更新 dll。如果您使用 dll 的应用程序不止 1 个,并且都需要 "right" 版本,其中 "right version" 不同,那么将 DLL 放置在 GAC 中会出现问题....
我有一个针对 .NETFramework 4.0(具有强名称)的程序集 (MYASM.dll)
我想在目标机器上以它是 .NETFramework(或整个系统认为是)的一部分的方式部署这个程序集。
我的意思是:
- .NET runtime see it at it sees System.dll(无需本地部署或提供参考路径)
- 当我执行
<Reference Include="MYASM" />
时,MSBuild 会看到它而无需提示路径 - 用户可以在 Visual Studio 中创建
Add reference
并且在没有 strong/full 名称的情况下引入<Reference Include="MYASM" />
我已经通过将其添加到 GAC 解决了 1.(显然还有 2.)。但这显然是不够的。
我已经部分解决了 3. 通过将我的程序集放在一个特殊的文件夹中 ([INSTALLFOLDER]\lib
) 并设置 registryKey HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\MyAssemblies
然后我可以添加引用,但我得到:
<Reference Include="MYASM, Version=1.1, Culture=neutral, ..." />
在我的 csproj 中,而不是我想要的 <Reference Include="MYASM" />
。
使用第二种方法,如果我手动编辑 csproj,一切正常,但我不能要求我的用户这样做。
我应该在这里做什么?
[编辑] 显然我有自己的 MSI 并不明显。但是,是的,我有。我不会用魔杖控制用户的机器
如果您有 MYASM.dll 的源代码,那么我更愿意为您的消费应用程序添加一个项目引用。这样做时,Visual Studio 将为所有引用的项目创建一个 GUID。
不,您已经尽力了。实际上,VS 如何将部分程序集名称放入项目文件中并不是那么明显。这不是 public 代码,不能被篡改。很确定它没有使用白名单,也无法关注参考程序集位置。
最有可能的细节是程序集的 PublicKeyToken。框架程序集始终具有完全相同的值,b77a5c561934e089。它的值甚至在 CLI 规范 (Ecma-335) 中有规定。接下来很可能是签名证书,将程序集标识为 Microsoft 拥有。然而,两者都存在完全相同的问题,您无法获得强名称或签署程序集所需的私钥。它们被锁在雷德蒙德的一个保险库中,只有受信任的构建工程师才能访问它们。
您还忽略了另一个讨厌的小细节,您对 DLL Hell 还不够害怕。冷酷的事实是,如果您 曾经 在另一台不受您控制的机器上公开 GAC 中的程序集,那么您将永远无法再次更改它。您不能再修改程序集的 public 界面。无法添加新的 public 方法或类型,无法修改方法的参数和 return 类型,无法添加枚举成员,等等。更苛刻的是,微软担心的是,是你也不能真正改变私人和内部成员。程序员有使用反射来四处寻找的诀窍,这是一种极好的错误修复工具。但至少你可以告诉他们 "don't do that!".
进行此类修改需要 增加 [AssemblyVersion]。现在你得到了一种不同类型的 DLL 地狱,机器可能没有被你的安装程序更新。或者更糟的是,一个解决方案使用具有不同引用的项目。 Microsoft 必须通过修改 CLR 来解决框架程序集的这个问题。自动将旧版本转发到新版本。使用为 .NET 2.0 构建的程序集的基本原因可以用于 .NET 4.x 项目。您无法为自己的 DLL 获取此类服务。
"Don't do it" 是唯一的好建议,但我可以向任何人推荐进入 DLL 地狱的麻烦是一个了不起的学习经验。地狱只有经历过才会害怕。
最好的建议是发布一个 Nuget 包。他们做的恰恰相反,从未部署在 GAC 中,版本号变化非常快。但在程序员需要时始终可用。
有几种方法...
1) 是为您的目标框架创建一个新的设置并将其打包。您可以将其打包并使用域控制器进行部署。当您的用户登录域时将更新软件包,这样您就可以将软件部署到特定用户,或者 user groups. Depending on your infrastructure 您将拥有一个可以使用的软件管理基础架构(包括 2 个链接) .
2) 如果您的目标是开发人员,请创建一个 NuGet 包。如果您的组织托管您自己的 NuGet 服务器,则限制分发。将包源添加到 Visual studio 打开选项页面,在搜索字段中键入 NuGet 并设置 URL/ UNC 路径。
3) 使用 OneClick 部署,这允许您让应用程序下载更新的 dll 并将它们安装在机器上。它需要一个代码签名证书,但你可能无论如何都要签署你的代码(如果你这样做,对反病毒工具来说更好)。
现在链接您的 MyAsam.dll 将由应用程序链接定义或 IoC 容器完成。基本上,如果它找到 dll 并且没有定义版本,它将采用它找到的第一个我认为顺序是 1 AppFolder、2 GAC、3 Path,不确定。此 "take what you find" 通常称为 "DLL-Hell",NuGet 和 OneClick 解决方案在这方面效果最好,因为您将始终获得适用于应用程序的更新 dll。如果您使用 dll 的应用程序不止 1 个,并且都需要 "right" 版本,其中 "right version" 不同,那么将 DLL 放置在 GAC 中会出现问题....