.net 绑定重定向在VSPackage/VSIX中无效

ycl3bljg  于 2023-01-27  发布在  .NET
关注(0)|答案(1)|浏览(97)

主要问题

我正在使用VS2017(15.9.25)开发VSIX VSPackage。
该包使用MySqlConnector 1.0.0 NuGet包,而MySqlConnector 1.0.0 NuGet包又依赖于包含System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51程序集的System.Memory 4.5.4 NuGet包。
当我使用Visual Studio Experimental Instance在调试模式下运行VSPackage时,我的插件会加载,并且我可以看到我的自定义选项页面和添加到VS上下文菜单中的自定义命令。但当我实际 * 运行 * 自定义命令(它尝试使用MySqlConnector检索一些数据)时,数据库连接失败,因为System.Memory程序集无法加载。

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

我的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的程序集资源管理器查看MySqlConnector.dll,我看到它引用了System.Memory 4.0.1.0,这是无法加载的程序集。
我的问题是:
1.为什么FileNotFoundException提到www.example.com绑定重定向不应该导致. NET尝试加载www.example.com吗? 4.0.1.0? Shouldn't the binding redirect cause .NET to try and load 4.0.1.1 , which is definitely present?
1.要在VSIX/VSPackage上下文中配置绑定重定向,我需要做什么特殊的事情吗?
1.额外的程序集绑定/加载诊断(例如=== Pre-bind state information ===等)实际上意味着什么?
1.要正确加载此程序集,需要进行哪些更改?

更多详情

我从标准的VS2017 VSIX包项目模板开始,它面向. NET 4.6,后来将我的项目重定向到. NET Framework 4.7.2。
我认为这个问题可能是由. NET Fx 4.7.2中包含的类型引起的,但在目标为. NET Fx 4.6时单独提供,所以我尝试在将目标更改为4.7.2后重新安装MySqlConnectorSystem.Memory NuGet包。
我使用的是传统的packages.config风格的NuGet配置。
VSIX软件包使用NuGet软件包MySqlConnector 1.0.0project home page),该软件包没有明确列出. NET 4.7.2的任何依赖项:

但是.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

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

但是,奇怪的是,在csproj文件中没有<AutoGenerateBindingRedirects>元素,也许由于某种原因,该元素不适用于VSIX项目,或者它在某个时候变成了隐式行为?
当我构建我的项目时,System.Memory.dll文件从NuGet packages文件夹复制到二进制输出文件夹,正如我所期望的那样:

使用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

tct7dpnv

tct7dpnv1#

答案似乎是.NET试图加载旧版本,因为VSPackage/VSIX项目do not honor binding redirects configured in app.config(由NuGet包安装/卸载操作维护),因为它们是在Visual Studio的devenv.exe上下文中加载的插件,该插件从VSIX无法编辑的其自己的devenv.exe.config文件中获取其主绑定重定向配置。
相反,VSIX基础结构允许在.pkgdef文件中配置绑定重定向,VS在加载VSPackage时会注意到这一点。.pkgdef文件是VSIX构建过程的输出。因此直接编辑它会相当脆弱。维护.pkgdef绑定重定向的最简单方法是将Microsoft.VisualStudio.Shell.ProvideBindingRedirectionAttribute的程序集范围内的示例添加到VSPackage项目“VSIX构建工具将拾取这些属性,并在构建VSIX时在.pkgdef文件中生成绑定重定向。
在基于app.config的内容添加了各种ProvideBindingRedirectionAttribute示例之后,现在可以加载MySqlConnector DLL了。

相关问题