问题描述
主要问题
我正在使用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
程序集无法加载。
我不完全理解的异常消息中提供了更多调试信息:
我的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.0
和System.Memory.dll 4.0.1.1
。
使用ReSharper的Assembly Explorer查看MySqlConnector.dll
,我看到它引用了System.Memory 4.0.1.0
,这是无法加载的程序集。
我的问题是:
- 为什么
FileNotFoundException
提到4.0.1.0?绑定重定向不应该导致.NET尝试加载肯定存在的4.0.1.1吗? - 在VSIX / VSPackage上下文中配置绑定重定向是否需要做些特别的事情?
- 额外的程序集绑定/加载诊断程序(例如
=== Pre-bind state information ===
等)实际上是什么意思? - 要使此程序集正确加载,我需要更改什么?
更多详细信息
我从标准的VS2017 VSIX包项目模板开始,该模板针对.NET 4.6,后来将我的项目重新定位到.NET Framework 4.7.2。
我认为问题可能是由.NET Fx 4.7.2中包含的类型引起的,但在针对.NET Fx 4.6时是单独提供的,因此我尝试重新安装MySqlConnector
和System.Memory
NuGet将目标更改为4.7.2之后的程序包。没关系。
我正在使用传统的packages.config
风格的NuGet配置。
VSIX软件包使用NuGet软件包MySqlConnector 1.0.0
(project 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
程序集的引用:
但是,奇怪的是,<AutoGenerateBindingRedirects>
文件中没有csproj
元素。也许该元素由于某种原因不适用于VSIX项目,或者在某些时候成为隐式行为?
在构建项目时,正如我期望的那样,System.Memory.dll
文件已从NuGet包文件夹复制到二进制输出文件夹中:
使用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
:
解决方法
似乎答案是.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。