重新组装装配不起作用

Nik*_*ola 9 .net c# msbuild .net-assembly xamarin

MSB3277在VS2015 RC中构建项目时收到错误代码.完整的信息是:

1> C:\程序文件(x86)\的MSBuild\14.0\BIN\Microsoft.Common.CurrentVersion.targets(1819,5):警告MSB3277:不同版本的相同依赖性组装的该不能被解析之间实测值冲突.当日志详细程度设置为详细时,这些引用冲突将在构建日志中列出.

所以我这样做了,我将输出更改为详细信息以查看发生了什么.

我的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>
Run Code Online (Sandbox Code Playgroud)

出现了更详细的错误:

2>考虑将版本"System.Net.Primitives,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a"的app.config重新映射从版本"3.9.0.0"[]到版本"4.0.0.0"[C:\ Program Files(x86)\参考Assemblies\Microsoft\Framework\MonoAndroid\v1.0\Facades\System.Net.Primitives.dll]解决冲突并摆脱警告.

app.config绑定,我曾经尝试都0.0.0.0-4.0.0.0oldVersion并指定一个确切的oldVersion,但结果都以同样的方式.

当我去System.Net.Http.Primitives它的属性时说:

  • 运行时版本: v4.0.30319
  • 版: 1.5.0.0

这是一个Xamarin项目,如果这无关紧要的话.

Xei*_*emm 0

当您拥有同一个 NuGet 的不同版本时,程序集绑定是一场噩梦。当我遇到类似问题时,我会使用三种方法。

  1. NuGet 包的整合。如果可能的话安装最新的和缺失的。
  2. 从代码中删除所有“ assemblyBinding”部分并重新安装所有 NuGet 包以获得当前设置的干净版本。
  3. 使用自定义 MSBuild 任务来解决问题,但您确实不想使用它。如果您可以将项目迁移到 .NET Core 库或仅迁移到 .NET SDK,请执行此操作。我必须强制重新映射所有内容,因为我有 100 多个项目与旧的 .NET Framework 绑定,而我无法轻松迁移这些项目。维护是一场噩梦,因此我创建了一个基于 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

来自 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>
Run Code Online (Sandbox Code Playgroud)