gpt4 book ai didi

.net - 使用 MSBuild, '$(SolutionDir)' 错误地解析为 C :\when running 'msbuild/t:restore'

转载 作者:行者123 更新时间:2023-12-04 00:23:41 24 4
gpt4 key购买 nike

我有 foo.csproj ,

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Globals">
<ExtPath>$(SolutionDir)\WpfNetStandardSample\CustomProjectSystem\</ExtPath>
</PropertyGroup>

<Import Project="$(ExtPath)CustomProject.props" />

</Project>

引用自解决方案文件 bar.sln .

要从持续集成服务器恢复我的 NuGet 包,我运行
msbuild /t:restore bar.sln

我得到了错误:

"C:\Users\phelan\workspace\bar\bar.sln" (restore target) (1) -> "C:\Users\phelan\workspace\bar\foo\foo.csproj" (_IsProjectRestoreSupported target) (11) -> C:\Users\phelan\workspace\bar\foo\foo.csproj(7,3): error MSB4019: The imported project "C:\WpfNetStandardSample\CustomProjectSystem\CustomProject.props" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.



主要问题

如何以及为什么解决方案目录 解析为 C:\而不是解决方案文件所在的目录?

笔记
  • 整个解决方案从 Visual Studio 中构建。
  • 运行msbuild foo.sln构建整个解决方案(假设 NuGet 包已经恢复)
  • MSBuild 版本为 15.3.409.57025
  • 解决方案是混合项目,一些使用packages.config,一些使用PackageReference。一些使用 PackageReference 的项目是 dotnetstandard 库,一些是 net461 库。
  • 关于如何恢复 NuGet 包似乎有各种各样的建议
  • dotnet restore
  • nuget restore Enter image description here
  • msbuild /t:restore
  • dotnet msbuild /t:restore foo.sln

  • 我的混合设置类型的正确流程是什么?

    用于重现错误的 GitHub 存储库

    https://github.com/bradphelan/msbuildbug

    最佳答案

    发生这种情况是因为对于解决方案的 Restore目标,SolutionDir不会传递给生成的项目引用。

    运行时可以看到:

    MSBuildEmitSolution=1 dotnet msbuild /t:Restore

    对于 foo.sln这将生成 foo.sln.metaproj包含解决方案格式的实际 MSBuild 解释的文件,以及添加的扩展名(例如 15.0/SolutionFile/ImportAfter/Microsoft.NuGet.ImportAfter.targets 在我们的例子中)。

    生成的 Build目标包含以下内容:
      <Target Name="Build" Outputs="@(CollectedBuildOutput)">
    <MSBuild Projects="@(ProjectReference)" BuildInParallel="True" Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)">
    <Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput" />
    </MSBuild>
    </Target>

    你可以看到这明确设置了 SolutionDir和其他与解决方案相关的属性。这同样适用于生成到解决方案中的许多其他目标。

    然而,NuGet 目标不这样做(技术原因是它们为项目和解决方案共享相同的 MSBuild 代码)。检查 <MSBuild> 时NuGet 创建的项目,它们不设置这些属性,因此在评估期间它们在项目中不可用。

    作为一种解决方法,我建议使用 MSBuild 15 的 Directory.Build.props 逻辑,将具有此名称的文件自动导入使用公共(public)属性/目标的所有项目(几乎所有项目类型)。

    在此文件中,放置在解决方案目录或它适用的项目上方的任何目录中,您可以设置要在项目中使用的变量 ( ExtPath ) 或直接设置所需的公共(public)属性:
    <Project>
    <PropertyGroup>
    <ExtPath>$(MSBuildThisFileDirectory)</ExtPath>
    <VersionPrefix>1.2.3</VersionPrefix>
    </PropertyGroup>
    <Import Project="$(ExtPath)Some\other.props" />
    </Project>

    关于.net - 使用 MSBuild, '$(SolutionDir)' 错误地解析为 C :\when running 'msbuild/t:restore' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46526428/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com