在 .Net 4.7.2 中导入 AngleSharp 时绑定重定向以某种方式尝试将 NetStandard 2 作为 dll 引入
Binding redirect when importing AngleSharp in .Net 4.7.2 somehow tries to pull in NetStandard 2 as a dll
我在旧的 Windows 2008 R2 服务器上有一个遗留应用程序 运行ning。该应用程序经历了许多 .Net 版本,目前为 4.7.2。它多年来一直稳定如磐石,虽然有迁移计划要搬离旧的物理服务器,但它必须再活一段时间。
一项新功能发现需要进行一些 HTML 抓取。我为 AngleSharp v0.12.0 添加了 NuGet 包,经过单元测试,在我的 Win10 开发机器上一切正常。使用 AngleSharp 的新 class 非常有效。
所以我部署到 prod 服务器,包括对 app.config;
的更改
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
</dependentAssembly>
</assemblyBinding>
</runtime>
这些是我能从旧版本中识别出的唯一变化。
当我 运行 生产中的应用程序时,它崩溃了。
System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
在网上做了一些搜索后,我看到有人指出了一个类似的问题(然而.Net Core,但仍然相似),他们指出尝试调用 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
可能会有所不同。参考:
https://github.com/DiscUtils/DiscUtils/issues/77
它不适合我,但现在我收到了更多时髦的消息:
System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
netstandard 是如何进入这个领域的?我不知道。由于 Splats 异常日志记录,我还在绑定日志中看到了这一点:
5496 === Pre-bind state information ===
5497 LOG: DisplayName = netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
5498 (Fully-specified)
5499 LOG: Appbase = file:///E:/dcollect/Ingest/
5500 LOG: Initial PrivatePath = NULL
5501 Calling assembly : System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
5502 ===
5503 LOG: This bind starts in default load context.
5504 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
5505 LOG: Using host configuration file:
5506 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
5507 LOG: Post-policy reference: netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
5508 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.DLL.
5509 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.DLL.
5510 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.EXE.
5511 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.EXE.
我的项目中没有(对我而言)已知的 Netstandard 引用,所有项目都是 .Net Framework 4.5、4.6.x 或 4.7.x 项目。
我也遇到了这一个似乎相关的问题:
https://github.com/dotnet/announcements/issues/31
我尝试将我的项目转换为 PackageReference 项目,但这也没有改变任何东西。
为了完整性,这里是我最初尝试使用 AngleSharp 的绑定日志。
5576 [20:24:01.522] <ERROR> EventParser: Exception caught: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
5577 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
5578 at AngleSharp.Browser.EncodingMetaHandler..ctor()
5579 at AngleSharp.Configuration..ctor(IEnumerable`1 services)
5580 at AngleSharp.Configuration.get_Default()
5581 at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
5582 === Pre-bind state information ===
5583 LOG: DisplayName = System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
5584 (Fully-specified)
5585 LOG: Appbase = file:///E:/dcollect/Ingest/
5586 LOG: Initial PrivatePath = NULL
5587 Calling assembly : AngleSharp, Version=0.11.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea.
5588 ===
5589 LOG: This bind starts in default load context.
5590 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
5591 LOG: Using host configuration file:
5592 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
5593 LOG: Post-policy reference: System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
5594 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
5595 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
5596 ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
我敢肯定这里肯定缺少一些简单的重定向魔法。是否有可能说服我的项目为 Net Framework v4.7.2 加载它并正常工作?
感谢任何建议!
编辑 5 月 14 日:
对我来说最混乱的一点是涉及的所有不同版本号。
AngleSharp 0.12.0 NuGet 包依赖于 System.Text.Encoding.CodePages >= 4.5.0。
因此即使 v4.5.1 存在,它也会自动安装 v4.5.0,因为依赖行为最低。
如果我右键单击放入我的 bin\Debug 文件夹中的实际 DLL,选择属性,然后选择版本,它会报告文件和产品版本 4.6.26515。
但在我的 app.config 中,我得到的绑定重定向是指 4.1.1.0。
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
(我尝试将 4.1.1.0 的两个实例替换为 4.6.26515.0 只是为了好玩,但没有任何改变)
然后,如上所述,日志声称:
29014 [22:42:44.735] <ERROR> EventInfoCreator: Failed to parse: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
29015 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
29016 at AngleSharp.Browser.EncodingMetaHandler..ctor()
29017 at AngleSharp.Configuration..ctor(IEnumerable`1 services)
29018 at AngleSharp.BrowsingContext.New(IConfiguration configuration)
29019 at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
29020 at Teller.Charts.DataCollection.EventParser.ParseFile(String filePath)
29021 at Teller.Charts.DataCollection.EventInfoCreator.CreateEventInfoProps(String html, String storageDirectory)
所以这里显然有一些版本不匹配,但坦率地说,我不知道这些版本号中哪个重要。
29034 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
29035 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
这似乎表明它对小版本不满意,但是...哪个?
AngleSharp 似乎要求的是 4.0.2.0?
app.config 指的是 4.1.1.0?
4.6.26515.0 是 dll 实际声称的版本?
在过去的一年里,我的团队 运行 遇到了各种绑定重定向问题,其中 System.Net.Http
、System.IO
和 System.Runtime
是添加错误重定向的主要原因.这给我们带来了很多痛苦,但我找到了一组解决问题的步骤。
- 从所有项目中删除所有绑定重定向
- 打开包管理器控制台
- 运行
Get-Project –All | Add-BindingRedirect
该命令将为您的项目添加所需的绑定重定向,但不会删除未使用的重定向,这就是为什么我添加了预先删除所有重定向的第一步。
对于几个包来说,这似乎有点像大锤,但我很惊讶它从我们公认的旧解决方案中删除了多少垃圾,同时解决了我们遇到的问题。
这个问题已经解决了。我无法完全解释解决方案,但我只是想把它放在这里,以防它可以帮助处于类似奇怪情况的其他人。
如前所述,运行环境为Win2008R2服务器。为 .Net 4.7.2 编译系统似乎工作正常,一直到 AngleSharp 被调用(然后它又拉入 CodePages 引用)。
现在,在与运行 AngleSharp 项目的 Florian 交谈后,他担心 GAC 中可能潜伏着一些邪恶的东西。我搜索了一下,一无所获 - 但注意到服务器上确实没有安装 .Net 4.7.2!我很快就发现了原因——这个古老的平台实际上不支持 4.6.2(?) 以上的版本。
这绝不能解释为什么我自己的代码 - 为 4.7.2 编译 - 运行 顺利,但一旦调用外部 class 库就被轰炸了。但是,它可能确实向比我更了解 .NET 运行时的人解释了这一点。
所以我将项目设置为 4.6.2 版,编译后,现在一切都运行得很顺利。加载任何依赖项或任何东西都没有问题。
回想起来这应该是显而易见的,但我坚持我的故事,因为我的可执行文件和至少一个 class 库正在为 4.7.2 编译并且仍然运行。
伙计们,请注意您的版本和平台支持。 :|
我在旧的 Windows 2008 R2 服务器上有一个遗留应用程序 运行ning。该应用程序经历了许多 .Net 版本,目前为 4.7.2。它多年来一直稳定如磐石,虽然有迁移计划要搬离旧的物理服务器,但它必须再活一段时间。
一项新功能发现需要进行一些 HTML 抓取。我为 AngleSharp v0.12.0 添加了 NuGet 包,经过单元测试,在我的 Win10 开发机器上一切正常。使用 AngleSharp 的新 class 非常有效。
所以我部署到 prod 服务器,包括对 app.config;
的更改 <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
</dependentAssembly>
</assemblyBinding>
</runtime>
这些是我能从旧版本中识别出的唯一变化。
当我 运行 生产中的应用程序时,它崩溃了。
System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
在网上做了一些搜索后,我看到有人指出了一个类似的问题(然而.Net Core,但仍然相似),他们指出尝试调用 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
可能会有所不同。参考:
https://github.com/DiscUtils/DiscUtils/issues/77
它不适合我,但现在我收到了更多时髦的消息:
System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
netstandard 是如何进入这个领域的?我不知道。由于 Splats 异常日志记录,我还在绑定日志中看到了这一点:
5496 === Pre-bind state information ===
5497 LOG: DisplayName = netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
5498 (Fully-specified)
5499 LOG: Appbase = file:///E:/dcollect/Ingest/
5500 LOG: Initial PrivatePath = NULL
5501 Calling assembly : System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
5502 ===
5503 LOG: This bind starts in default load context.
5504 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
5505 LOG: Using host configuration file:
5506 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
5507 LOG: Post-policy reference: netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
5508 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.DLL.
5509 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.DLL.
5510 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.EXE.
5511 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.EXE.
我的项目中没有(对我而言)已知的 Netstandard 引用,所有项目都是 .Net Framework 4.5、4.6.x 或 4.7.x 项目。
我也遇到了这一个似乎相关的问题:
https://github.com/dotnet/announcements/issues/31
我尝试将我的项目转换为 PackageReference 项目,但这也没有改变任何东西。
为了完整性,这里是我最初尝试使用 AngleSharp 的绑定日志。
5576 [20:24:01.522] <ERROR> EventParser: Exception caught: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
5577 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
5578 at AngleSharp.Browser.EncodingMetaHandler..ctor()
5579 at AngleSharp.Configuration..ctor(IEnumerable`1 services)
5580 at AngleSharp.Configuration.get_Default()
5581 at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
5582 === Pre-bind state information ===
5583 LOG: DisplayName = System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
5584 (Fully-specified)
5585 LOG: Appbase = file:///E:/dcollect/Ingest/
5586 LOG: Initial PrivatePath = NULL
5587 Calling assembly : AngleSharp, Version=0.11.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea.
5588 ===
5589 LOG: This bind starts in default load context.
5590 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
5591 LOG: Using host configuration file:
5592 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
5593 LOG: Post-policy reference: System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
5594 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
5595 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
5596 ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
我敢肯定这里肯定缺少一些简单的重定向魔法。是否有可能说服我的项目为 Net Framework v4.7.2 加载它并正常工作?
感谢任何建议!
编辑 5 月 14 日: 对我来说最混乱的一点是涉及的所有不同版本号。
AngleSharp 0.12.0 NuGet 包依赖于 System.Text.Encoding.CodePages >= 4.5.0。
因此即使 v4.5.1 存在,它也会自动安装 v4.5.0,因为依赖行为最低。
如果我右键单击放入我的 bin\Debug 文件夹中的实际 DLL,选择属性,然后选择版本,它会报告文件和产品版本 4.6.26515。
但在我的 app.config 中,我得到的绑定重定向是指 4.1.1.0。
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
(我尝试将 4.1.1.0 的两个实例替换为 4.6.26515.0 只是为了好玩,但没有任何改变)
然后,如上所述,日志声称:
29014 [22:42:44.735] <ERROR> EventInfoCreator: Failed to parse: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
29015 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
29016 at AngleSharp.Browser.EncodingMetaHandler..ctor()
29017 at AngleSharp.Configuration..ctor(IEnumerable`1 services)
29018 at AngleSharp.BrowsingContext.New(IConfiguration configuration)
29019 at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
29020 at Teller.Charts.DataCollection.EventParser.ParseFile(String filePath)
29021 at Teller.Charts.DataCollection.EventInfoCreator.CreateEventInfoProps(String html, String storageDirectory)
所以这里显然有一些版本不匹配,但坦率地说,我不知道这些版本号中哪个重要。
29034 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
29035 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
这似乎表明它对小版本不满意,但是...哪个?
AngleSharp 似乎要求的是 4.0.2.0? app.config 指的是 4.1.1.0? 4.6.26515.0 是 dll 实际声称的版本?
在过去的一年里,我的团队 运行 遇到了各种绑定重定向问题,其中 System.Net.Http
、System.IO
和 System.Runtime
是添加错误重定向的主要原因.这给我们带来了很多痛苦,但我找到了一组解决问题的步骤。
- 从所有项目中删除所有绑定重定向
- 打开包管理器控制台
- 运行
Get-Project –All | Add-BindingRedirect
该命令将为您的项目添加所需的绑定重定向,但不会删除未使用的重定向,这就是为什么我添加了预先删除所有重定向的第一步。
对于几个包来说,这似乎有点像大锤,但我很惊讶它从我们公认的旧解决方案中删除了多少垃圾,同时解决了我们遇到的问题。
这个问题已经解决了。我无法完全解释解决方案,但我只是想把它放在这里,以防它可以帮助处于类似奇怪情况的其他人。
如前所述,运行环境为Win2008R2服务器。为 .Net 4.7.2 编译系统似乎工作正常,一直到 AngleSharp 被调用(然后它又拉入 CodePages 引用)。
现在,在与运行 AngleSharp 项目的 Florian 交谈后,他担心 GAC 中可能潜伏着一些邪恶的东西。我搜索了一下,一无所获 - 但注意到服务器上确实没有安装 .Net 4.7.2!我很快就发现了原因——这个古老的平台实际上不支持 4.6.2(?) 以上的版本。
这绝不能解释为什么我自己的代码 - 为 4.7.2 编译 - 运行 顺利,但一旦调用外部 class 库就被轰炸了。但是,它可能确实向比我更了解 .NET 运行时的人解释了这一点。
所以我将项目设置为 4.6.2 版,编译后,现在一切都运行得很顺利。加载任何依赖项或任何东西都没有问题。
回想起来这应该是显而易见的,但我坚持我的故事,因为我的可执行文件和至少一个 class 库正在为 4.7.2 编译并且仍然运行。
伙计们,请注意您的版本和平台支持。 :|