0

主要问题

我正在使用 VS2017 (15.9.25) 开发 VSIX VSPackage。

该包使用MySqlConnector 1.0.0NuGet 包,而 NuGet 包又依赖于System.Memory 4.5.4包含System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51程序集的 NuGet 包。

当我使用 Visual Studio 实验实例在调试模式下运行我的 VSPackage 时,我的插件会加载,我可以看到我的自定义选项页面和我添加到 VS 上下文菜单的自定义命令。但是当我实际运行自定义命令(尝试使用 检索一些数据MySqlConnector)时,数据库连接失败,因为System.Memory程序集无法加载。

FileNotFoundException 详细信息

异常消息中提供了一些我不完全理解的调试信息:

附加装配加载细节

Myapp.config包含以下绑定重定向:

  <dependentAssembly>
    <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
  </dependentAssembly>

bin/Debug文件夹和生成的.vsix文件都包含MySqlConnector.dll 1.0.0System.Memory.dll 4.0.1.1

查看MySqlConnector.dll使用 ReSharper 的程序集资源管理器,我看到它引用System.Memory 4.0.1.0了,这是无法加载的程序集。

我的问题是:

  1. 为什么FileNotFoundException提到4.0.1.0?绑定重定向不应该导致 .NET 尝试加载肯定存在的 4.0.1.1 吗?
  2. 在 VSIX/VSPackage 上下文中配置绑定重定向需要做些什么特别的事情吗?
  3. 额外的程序集绑定/加载诊断(例如=== Pre-bind state information ===等)实际上意味着什么?
  4. 我需要更改哪些内容才能正确加载此程序集?

更多细节

我从面向 .NET 4.6 的标准 VS2017 VSIX 包项目模板开始,后来将我的项目重新定位到 .NET Framework 4.7.2。

我认为该问题可能是由 .NET Fx 4.7.2 中包含的类型引起的,但在针对 .NET Fx 4.6 时是单独提供的,因此我尝试在将目标更改为 4.7.2 后重新安装 theMySqlConnectorSystem.MemoryNuGet 包。它没有任何区别。

我正在使用传统packages.config风格的 NuGet 配置。

VSIX 包使用 NuGet 包MySqlConnector 1.0.0项目主页)。该包没有明确列出 .NET 4.7.2 的任何依赖项:

NuGet 包管理器中的 MySqlConnector 依赖项列表

但似乎依赖项.NETFramework,Version=4.7.1也适用于4.7.2,因为安装MySqlConnector会导致System.Memory 4.5.4NuGet 包也被安装。这会将System.Memory 4.0.1.1程序集的引用添加到我的 VSIX VSPackage 项目中,其中包含Copy Local == True

System.Memory 引用属性

选中项目属性中“自动生成绑定重定向”的复选框: 检查自动生成绑定重定向

但是,奇怪的是,文件中没有<AutoGenerateBindingRedirects>元素。csproj也许该元素由于某种原因不适用于 VSIX 项目,或者它在某些时候变成了隐式行为?

当我构建我的项目时,该System.Memory.dll文件正在从 NuGet 包文件夹复制到二进制输出文件夹中,正如我所期望的:

Windows 资源管理器屏幕截图在输出文件夹中显示 System.Memory.dll

使用 ILSpy 检查二进制输出文件夹中的文件证明它是最新版本,并且与以下中的程序集绑定重定向匹配app.config

// C:\git\[redacted]\bin\Debug\System.Memory.dll
// System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// Global type: <Module>
// Architecture: AnyCPU (64-bit preferred)
// Runtime: v4.0.30319
// This assembly is signed with a strong name key.
// Hash algorithm: SHA1

使用 7-zip打开.vsix输出文件夹中的文件显示 VSIX 还包含System.Memory.dll

VSIX 存档内容

4

1 回答 1

0

似乎答案是 .NET 试图加载旧版本,因为 VSPackage/VSIX 项目不支持配置的绑定重定向app.config(由 NuGet 包安装/卸载操作维护),因为它们是在上下文中加载的插件Visual Studio 的,它从VSIX 无法编辑devenv.exe的自己的文件中获取其主要绑定重定向配置。devenv.exe.config

相反,VSIX 基础结构允许在.pkgdef文件中配置绑定重定向,VS 在加载 VSPackage 时会注意这一点。该.pkgdef文件是 VSIX 构建过程的输出,因此直接编辑它会相当脆弱。维护 .pkgdef 绑定重定向的最简单方法是将 的程序集范围实例添加Microsoft.VisualStudio.Shell.ProvideBindingRedirectAttribute到 VSPackage 项目的AssemblyInfo.cs文件中。VSIX 构建工具将在构建 VSIX 时获取这些属性并在.pkgdef文件中生成绑定重定向。

ProvideBindingRedirectAttribute根据我的内容添加各种实例后app.config,我现在可以加载MySqlConnectorDLL。

于 2020-08-12T03:59:03.680 回答