程序集的重新映射不起作用
本文关键字:映射 不起作用 新映射 程序集 | 更新日期: 2023-09-27 18:18:44
当我在VS2015 RC中构建我的项目时,我得到了MSB3277
错误代码。完整的信息是:
1> C: '程序文件(x86) ' [' 14.0 ' bin ' Microsoft.Common.CurrentVersion.targets (1819 5):的不同版本之间存在冲突无法解析的相同从属程序集。这些参考当日志详细度设置为时,冲突将在构建日志中列出详细。
所以我这样做了,我把我的输出更改为详细,看看发生了什么。
我的app.config是这样的:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="3.9.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
出现了更详细的错误:
2>考虑重新映射程序集"System.Net.Primitives,文化=中性,PublicKeyToken=b03f5f7f11d50a3a"从版本"3.9.0.0"[]版本"4.0.0.0" [C:'Program Files (x86)'Reference微软组件' ' Framework ' MonoAndroid ' v1.0 '外墙' System.Net.Primitives.dll]化解冲突,摆脱警告。
在app.config
绑定上,我尝试了0.0.0.0-4.0.0.0
作为oldVersion
并指定了确切的oldVersion
,但两者都以相同的方式产生。
当我进入System.Net.Http.Primitives
的属性时它显示:
- 运行版本:
- 版本:
1.5.0.0
v4.0.30319
这是一个Xamarin项目。
当同一个NuGet有不同版本时,程序集绑定是一场噩梦。当我遇到类似的问题时,我使用了三种方法。
- NuGet包的整合。如果可能,安装最新的和丢失的。
- 删除所有的assemblyBinding",并重新安装所有NuGet包,以获得当前安装的干净版本。
- 使用自定义MSBuild任务来解决问题,但你真的不想使用它。如果你可以将你的项目迁移到。net Core库或。net SDK,那就去做吧。我不得不重新映射它,因为我有100多个项目与旧的。net框架绑定,我不能轻易迁移。维护是一场噩梦,所以我创建了一个基于MSBuild的任务。
namespace YourNamespace.Sdk
{
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class GenerateConfigBindingRedirects : Task
{
public string ConfigFilePath { get; set; }
public ITaskItem[] SuggestedBindingRedirects { get; set; }
public override bool Execute()
{
if (this.SuggestedBindingRedirects == null || this.SuggestedBindingRedirects.Length == 0)
{
return true;
}
var doc = XDocument.Load(this.ConfigFilePath);
if (doc == null)
{
return false;
}
var runtimeNode = doc.Root.Nodes().OfType<XElement>().FirstOrDefault(e => e.Name.LocalName == "runtime");
if (runtimeNode == null)
{
runtimeNode = new XElement("runtime");
doc.Root.Add(runtimeNode);
}
else
{
return false;
}
var ns = XNamespace.Get("urn:schemas-microsoft-com:asm.v1");
var redirectNodes = from redirect in this.ParseSuggestedRedirects()
select new XElement(
ns + "dependentAssembly",
new XElement(
ns + "assemblyIdentity",
new XAttribute("name", redirect.Key.Name),
new XAttribute("publicKeyToken", GetPublicKeyToken(redirect.Key.GetPublicKeyToken())),
new XAttribute("culture", string.IsNullOrEmpty(redirect.Key.CultureName) ? "neutral" : redirect.Key.CultureName)),
new XElement(
ns + "bindingRedirect",
new XAttribute("oldVersion", "0.0.0.0-" + redirect.Value),
new XAttribute("newVersion", redirect.Value)));
var assemblyBinding = new XElement(ns + "assemblyBinding", redirectNodes);
runtimeNode.Add(assemblyBinding);
using (var stream = new StreamWriter(this.ConfigFilePath))
{
doc.Save(stream);
}
return true;
}
private static string GetPublicKeyToken(byte[] bytes)
{
var builder = new StringBuilder();
for (var i = 0; i < bytes.GetLength(0); i++)
{
builder.AppendFormat("{0:x2}", bytes[i]);
}
return builder.ToString();
}
private IDictionary<AssemblyName, string> ParseSuggestedRedirects()
{
var map = new Dictionary<AssemblyName, string>();
foreach (var redirect in this.SuggestedBindingRedirects)
{
try
{
var maxVerStr = redirect.GetMetadata("MaxVersion");
var assemblyIdentity = new AssemblyName(redirect.ItemSpec);
map.Add(assemblyIdentity, maxVerStr);
}
catch
{
}
}
return map;
}
}
}
namespace YourNamespace.Sdk
{
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Build.Utilities;
public class RemoveRuntimeNode : Task
{
public string ConfigFilePath { get; set; }
public override bool Execute()
{
var doc = XDocument.Load(this.ConfigFilePath);
if (doc == null)
{
return false;
}
doc.Root.Nodes().OfType<XElement>().FirstOrDefault(e => e.Name.LocalName == "runtime")?.Remove();
using (var stream = new StreamWriter(this.ConfigFilePath))
{
doc.Save(stream);
}
return true;
}
}
}
从csproj: <?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.4.0" />
</ItemGroup>
<UsingTask TaskName="RemoveRuntimeNode" AssemblyFile="$([MSBuild]::ValueOrDefault('$(YourLibPath)', '$(MSBuildThisFileDirectory)..'lib'netstandard2.0'YourNamespace.Sdk.dll'))" />
<UsingTask TaskName="GenerateConfigBindingRedirects" AssemblyFile="$([MSBuild]::ValueOrDefault('$(YourLibPath)', '$(MSBuildThisFileDirectory)..'lib'netstandard2.0'YourNamespace.Sdk.dll'))" />
<Target Name="RemoveConfigRuntimeNode" BeforeTargets="ResolveAssemblyReferences" Condition="Exists('$(MSBuildProjectDirectory)'app.config')">
<RemoveRuntimeNode ConfigFilePath="$(MSBuildProjectDirectory)'app.config" />
</Target>
<Target Name="GenerateConfigBindingRedirects" AfterTargets="RemoveConfigRuntimeNode" Condition="Exists('$(MSBuildProjectDirectory)'app.config')">
<GenerateConfigBindingRedirects ConfigFilePath="$(MSBuildProjectDirectory)'app.config" SuggestedBindingRedirects="@(SuggestedBindingRedirects)"/>
</Target>
</Project>