Visual Studio 错误地引用了 nuget 包 /build 目录中的程序集
Visual Studio incorrectly referencing assembly from nuget package /build directory
我有一个 C# 项目 (ProjectA) 在单独的进程中调用另一个 C# 项目 (ProjectB)。构建输出目录结构为:
/ProjectA.exe
/ProjectB/ProjectB.exe
ProjectA 和 ProjectB 引用同一程序集的不同版本,在本例中为 Newtonsoft.Json.dll。
构建输出目录结构是通过将ProjectB 的nuget 包添加到ProjectA 来实现的。 ProjectA 和 ProjectB 在不同的解决方案中并单独构建。 ProjectB 的 nuget 包是使用以下 .nuspec 和 .targets 创建的。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)*" />
<Content Include="@(NativeLibs)">
<Link>ProjectB\%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
我的问题是 ProjectA 正在引用 ProjectB nuget 包 /build 目录中较新的 Newtonsoft.Json.dll,而不是 ProjectA 解决方案中较旧的 Newtonsoft.Json.dll。它们是不同的版本,因此这会在运行时引起问题。我意识到我可以在 ProjectA 解决方案中更新 Newtonsoft.Json.dll 的版本,但我希望能够在不可能的情况下解决更一般的情况。如何防止Visual Studio找错Newtonsoft.Json.dll?
编辑:这个答案实际上不起作用。 VisualStudio 的行为在决定使用哪个程序集方面非常不一致。有时从输出目录中删除程序集会导致最终使用的程序集版本发生变化。显然,任何链接到项目的程序集文件都可以在编译时由 MSBuild 选择。请参阅我的 。
我发现如果我将所有 ProjectB 程序集放在 nuget 包 /build 目录的单独子目录中,则 MSBuild 不会将它们用作引用。
ProjectB 的工作 nuget 包是使用以下 .nuspec 和 .targets 创建的。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build/ProjectB" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)ProjectB\*" />
<None Include="@(NativeLibs)">
<Link>ProjectB\%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
显然,MSBuild 正在与 ProjectB.targets 文件相同的目录中查找匹配的程序集,而不是子目录。 MSBuild 的这种 "magic" 行为确实应该由 Microsoft 修复。查看相关 comment to this question
最后,添加包含所有 ProjectB 程序集的链接项组总是导致将错误的程序集版本拉入 ProjectA 的问题。我不得不求助于 robocopy postbuild 命令来做我想做的事。这有一个缺点,即当另一个项目引用 ProjectA 时,不会复制 ProjectB 程序集,但这对我来说并不重要。如果 Microsoft 曾修复 this behavior with magic assembly paths,那么原始问题中的 nuget 包应该可以正常工作。以下是带有 robocopy 解决方法的 .nuspec 和 .targets 文件。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build/ProjectB" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="ProjectBCopyTarget" AfterTargets="Build">
<Exec Command="robocopy /PURGE $(MSBuildThisFileDirectory)ProjectB $(TargetDir)ProjectB || if %ERRORLEVEL% LSS 8 exit 0"/>
</Target>
</Project>
我有一个 C# 项目 (ProjectA) 在单独的进程中调用另一个 C# 项目 (ProjectB)。构建输出目录结构为:
/ProjectA.exe
/ProjectB/ProjectB.exe
ProjectA 和 ProjectB 引用同一程序集的不同版本,在本例中为 Newtonsoft.Json.dll。
构建输出目录结构是通过将ProjectB 的nuget 包添加到ProjectA 来实现的。 ProjectA 和 ProjectB 在不同的解决方案中并单独构建。 ProjectB 的 nuget 包是使用以下 .nuspec 和 .targets 创建的。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)*" />
<Content Include="@(NativeLibs)">
<Link>ProjectB\%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
我的问题是 ProjectA 正在引用 ProjectB nuget 包 /build 目录中较新的 Newtonsoft.Json.dll,而不是 ProjectA 解决方案中较旧的 Newtonsoft.Json.dll。它们是不同的版本,因此这会在运行时引起问题。我意识到我可以在 ProjectA 解决方案中更新 Newtonsoft.Json.dll 的版本,但我希望能够在不可能的情况下解决更一般的情况。如何防止Visual Studio找错Newtonsoft.Json.dll?
编辑:这个答案实际上不起作用。 VisualStudio 的行为在决定使用哪个程序集方面非常不一致。有时从输出目录中删除程序集会导致最终使用的程序集版本发生变化。显然,任何链接到项目的程序集文件都可以在编译时由 MSBuild 选择。请参阅我的
我发现如果我将所有 ProjectB 程序集放在 nuget 包 /build 目录的单独子目录中,则 MSBuild 不会将它们用作引用。 ProjectB 的工作 nuget 包是使用以下 .nuspec 和 .targets 创建的。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build/ProjectB" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)ProjectB\*" />
<None Include="@(NativeLibs)">
<Link>ProjectB\%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
显然,MSBuild 正在与 ProjectB.targets 文件相同的目录中查找匹配的程序集,而不是子目录。 MSBuild 的这种 "magic" 行为确实应该由 Microsoft 修复。查看相关 comment to this question
最后,添加包含所有 ProjectB 程序集的链接项组总是导致将错误的程序集版本拉入 ProjectA 的问题。我不得不求助于 robocopy postbuild 命令来做我想做的事。这有一个缺点,即当另一个项目引用 ProjectA 时,不会复制 ProjectB 程序集,但这对我来说并不重要。如果 Microsoft 曾修复 this behavior with magic assembly paths,那么原始问题中的 nuget 包应该可以正常工作。以下是带有 robocopy 解决方法的 .nuspec 和 .targets 文件。
<?xml version="1.0"?>
<package>
<metadata>
<id>ProjectB</id>
<version>$version$</version>
<title>ProjectB</title>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ProjectB</description>
<copyright>Copyright 2016</copyright>
<tags>ProjectB</tags>
</metadata>
<files>
<file src="x64\Release\*" target="build/ProjectB" />
<file src="ProjectB.targets" target="build/ProjectB.targets" />
</files>
</package>
。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="ProjectBCopyTarget" AfterTargets="Build">
<Exec Command="robocopy /PURGE $(MSBuildThisFileDirectory)ProjectB $(TargetDir)ProjectB || if %ERRORLEVEL% LSS 8 exit 0"/>
</Target>
</Project>