绑定重定向在VSPackage / VSIX中无效 主要问题更多详细信息

问题描述

主要问题

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

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

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

FileNotFoundException details

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

additional assembly loading details

我的app.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

使用ReSharper的Assembly Explorer查看MySqlConnector.dll,我看到它引用了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. 要使此程序集正确加载,我需要更改什么?

更多详细信息

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

我认为问题可能是由.NET Fx 4.7.2中包含的类型引起的,但在针对.NET Fx 4.6时是单独提供的,因此我尝试重新安装MySqlConnectorSystem.Memory NuGet将目标更改为4.7.2之后的程序包。没关系。

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

VSIX软件包使用NuGet软件包MySqlConnector 1.0.0project home page)。该软件包没有明确列出.NET 4.7.2的任何依赖项:

MySqlConnector dependency list from NuGet package manager

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

System.Memory reference properties

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

auto-generate binding redirects is checked

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

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

Windows explorer screencap showing System.Memory.dll in output folder

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

// C:\git\[redacted]\bin\Debug\System.Memory.dll
// System.Memory,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 archive contents

解决方法

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

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

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...