【问题标题】:Deploy assembly as part of .Net Framework将程序集部署为 .Net Framework 的一部分
【发布时间】:2018-12-06 02:01:22
【问题描述】:

我有一个针对 .NETFramework 4.0(具有强名称)的程序集 (MYASM.dll)

我想在目标机器上以它是 .NETFramework 的一部分(或整个系统认为它的一部分)的方式部署这个程序集。

我的意思是:

  1. .NET 运行时看到 System.dll(无需本地部署或提供参考路径)
  2. 当我在不需要提示路径的情况下执行 <Reference Include="MYASM" /> 时,MSBuild 会看到它
  3. 用户可以在 Visual Studio 中创建 Add reference 并在没有强/全名的情况下引入 <Reference Include="MYASM" />

我已经通过将 1.(显然是 2.)添加到 GAC 来解决它。但这显然还不够。

我已经部分解决了 3. 通过将我的程序集放在一个特殊的文件夹 ([INSTALLFOLDER]\lib) 并设置 registryKey HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\MyAssemblies

然后我可以添加参考,但我会在我的 csproj 中得到:
<Reference Include="MYASM, Version=1.1, Culture=neutral, ..." />,而不是我想要的 <Reference Include="MYASM" />

使用第二种方法,如果我手动编辑 csproj,一切正常,但我不能要求我的用户这样做。

我应该在这里做什么?

[编辑] 显然我有自己的 MSI 并不明显。但是是的,我有。我不会用魔杖控制用户机器

【问题讨论】:

  • @jonskeet 请帮帮我! :)
  • 第一,您不能只将程序集放到 .net 框架中。您需要一个自己的安装程序,它将把它放在每台客户端机器上的 GAC 中。第二,你在这里看到的<Reference Include="MYASM, Version=1.1, Culture=neutral, ..." /> 是一个强名称,所以如果你的程序集是强名称,那么你应该添加一个引用。
  • 我有一个自定义安装程序可以将程序集放入 GAC。当我删除强名称时,我仍然对 有同样的问题
  • 并且 System.dll 也已签名。没有那个 问题。
  • 你可以试试这个community.flexerasoftware.com/…

标签: c# .net visual-studio assemblies gac


【解决方案1】:

不,您已经尽其所能。实际上,VS 如何将部分程序集名称放入项目文件中并不那么明显。这不是公共代码,不能被篡改。很确定它没有使用白名单,也无法关注参考程序集位置。

最有可能的细节是程序集的 PublicKeyToken。框架程序集必须始终具有完全相同的值,b77a5c561934e089。它的值甚至在 CLI 规范 (Ecma-335) 中都有规定。接下来很可能是签名证书,将程序集标识为 Microsoft 拥有。然而,两者都存在完全相同的问题,您无法获得强名称或签署程序集所需的私钥。它们被锁在雷德蒙德的一个保险库中,只有受信任的构建工程师才能访问它们。

您忽略了另一个令人讨厌的小细节,您对 DLL Hell 的恐惧还不够。冷酷的事实是,如果您曾经在另一台不受您控制的机器上公开 GAC 中的程序集,那么您将永远无法再次更改它。您不能再修改程序集的公共接口。不能添加新的公共方法或类型,不能修改方法的参数和返回类型,不能添加枚举成员等等。更苛刻的是,微软担心的是你不能真正改变私人和内部成员。程序员有使用反射的诀窍,非常棒的错误修复工具。但至少你可以告诉他们“不要那样做!”。

进行此类修改需要增加 [AssemblyVersion]。现在你得到了另一种 DLL Hell,你的安装程序可能没有更新机器。或者更糟糕的是,解决方案使用具有不同引用的项目。微软不得不为框架程序集解决这个问题,他们通过修改 CLR 来解决这个问题。自动将旧版本转发到新版本。使用为 .NET 2.0 构建的程序集可用于 .NET 4.x 项目的基本原因。您无法为自己的 DLL 获得这种服务。

“不要这样做”是唯一的好建议,但陷入 DLL Hell 的麻烦是我可以向任何人推荐的极好的学习体验。必须经历地狱才能害怕。

最好的建议是发布 Nuget 包。他们做的恰恰相反,从未在 GAC 中部署,而且版本号变化非常迅速。但在程序员需要时始终可用。

【讨论】:

  • 谢谢。 b77a5c561934e089 是关键 :) 我想我会放弃 GAC 并添加参考资料 :)
  • 我希望得到某个微软开发者的确认。
【解决方案2】:

有几种方法...

1) 是为您的目标框架创建一个新设置并将其打包。您可以将其打包并使用域控制器进行部署。当您的用户登录域时,将更新软件包,这样您就可以将您的软件部署到特定用户和或user groups。根据您的infrastructure,您将拥有一个可以使用的软件管理基础架构(包括 2 个链接)。

2) 如果您面向开发人员,请创建一个 NuGet 包。如果您的组织托管您自己的 NuGet 服务器,则会限制分发。将包源添加到 Visual Studio 打开选项页面,在搜索字段中键入 NuGet 并设置 URL/UNC 路径。

3) 使用 OneClick 部署,这允许您让应用程序下载更新的 dll 并将它们安装在机器上。它需要一个代码签名证书,但您可能无论如何都在对您的代码进行签名(如果您这样做,则更好地使用防病毒工具)。

现在链接您的 MyAsam.dll 将由应用程序链接定义或 IoC 容器完成。基本上,如果它找到 dll 并且没有定义任何版本,它将采用它找到的第一个我认为顺序是 1 AppFolder、2 GAC、3 Path,不确定。这种“取你所见”通常被称为“DLL-Hell”,NuGet 和 OneClick 解决方案在这方面效果最好,因为您将始终获得适用于应用程序的更新的 dll。如果您有超过 1 个应用程序使用您的 dll,并且两者都需要“正确”版本,其中“正确版本”不同......

【讨论】:

    【解决方案3】:

    如果您有可用于 MYASM.dll 的源代码,那么我希望将项目引用添加到您的消费应用程序。这样做时,Visual Studio 将为所有引用的项目创建一个 GUID。

    【讨论】:

    • 我不能在用户的机器上这样做。
    • 如何为程序集创建一个 Nuget 包,每次构建解决方案时都会自动下载更新的包?
    猜你喜欢
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多