Unity生成的csproj在VS2015中报CS1703重复程序集导入错误
问题概述
当你在Unity 2018.1中创建.NET 4.6项目,切换脚本运行时版本为.NET 4.x后,在Visual Studio 2015中构建会触发大量CS1703: Multiple assemblies with equivalent identity have been imported错误,且Unity控制台无报错。这是因为Unity自带的Mono BCL程序集与VS2015引入的系统.NET Framework程序集发生了重复引用冲突,而Unity自动生成的.csproj文件无法手动修改(修改后会被Unity覆盖)。
解决方案
1. 升级Visual Studio版本(推荐)
VS2015对Unity的.NET 4.x运行时兼容性有限,升级到Visual Studio 2017或更高版本可以直接解决这个问题。这些版本的VS对Unity项目的程序集引用处理做了优化,能自动识别并避免Unity自带程序集与系统.NET程序集的冲突,无需额外配置。
2. 使用Unity Editor脚本自动修复重复引用
如果你暂时无法升级VS,可以编写一个Editor脚本,让Unity在生成.csproj文件后自动移除重复的程序集引用:
- 在Unity项目中创建
Editor文件夹(若不存在) - 在该文件夹下新建C#脚本,命名为
FixDuplicateAssemblies.cs,粘贴以下代码:
using UnityEditor; using System.IO; using System.Xml.Linq; using System.Collections.Generic; public class FixDuplicateAssemblies : AssetPostprocessor { static void OnGeneratedCSProjectFiles() { // 获取项目根目录下的所有.csproj文件 var projectFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj", SearchOption.TopDirectoryOnly); foreach (var projectPath in projectFiles) { var doc = XDocument.Load(projectPath); var ns = doc.Root.Name.Namespace; var referenceElements = doc.Descendants(ns + "Reference"); var seenAssemblyNames = new HashSet<string>(); var duplicateReferences = new List<XElement>(); foreach (var reference in referenceElements) { var includeAttr = reference.Attribute("Include"); if (includeAttr == null) continue; // 提取程序集名称(忽略版本、公钥等信息) var assemblyFullName = includeAttr.Value; var assemblyName = assemblyFullName.Split(',')[0]; if (seenAssemblyNames.Contains(assemblyName)) { duplicateReferences.Add(reference); } else { seenAssemblyNames.Add(assemblyName); } } // 移除重复引用 foreach (var duplicate in duplicateReferences) { duplicate.Remove(); } doc.Save(projectPath); } } }
- 保存脚本后,Unity会在每次生成/更新
.csproj文件时自动运行这个脚本,移除重复的程序集引用。之后再在VS中构建项目,错误就会消失。
问题原因
Unity的.NET 4.x运行时基于Mono实现,自带了一套BCL(Base Class Library)程序集;而Visual Studio 2015的MSBuild在处理Unity项目时,会自动引入系统的.NET Framework 4.6程序集。这两套程序集的标识(名称、版本等)高度重合,导致编译器认为存在重复引用,从而触发CS1703错误。由于Unity会持续自动生成.csproj文件,手动修改的内容会被覆盖,因此需要通过升级工具或自动脚本的方式解决。
内容的提问来源于stack exchange,提问作者Etienne de Martel




