0

我们有一个通过 VisualStudio2017 创建和维护的解决方案,其中我们的.csprojs被放置在虚拟文件夹中,如下所示:

Solution.sln
  \- VirtualFolder1
       \- Foo.Common.Bar.csproj -> Bar\bin
       \- Foo.Common.Ping.csproj -> Ping\bin
       \- Foo.Common.Pong.csproj -> Pong\bin
  \- VirtualFolder2
       \- Foo.Utils.Bar.csproj -> Utils.Bar\bin
       \- Foo.Utils.Ping.csproj -> Utils.Ping\bin
       \- Foo.Utils.Pong.csproj -> Utils.Pong\bin

正如预期的那样,每个 .csproj 文件都已经包含一个定义输出路径应该在哪里的部分:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>[Bar/bin or Ping/bin etc]</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7.1</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>[Bar/bin or Ping/bin etc]</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7.1</LangVersion>
  </PropertyGroup>

我们希望将所有.Common .csproj.Utils .csproj项目整体构建到各自的输出文件夹中,而不必在我们的 msbuild-script(由 JenkinsCI btw 调用)中一一指定。为了实现这一点,我们尝试了:

<ItemGroup>      
  <ALL_PROJECTS_IN_SOLUTION_EXCEPT_TESTS
    Include="$(_codeFolderpath)\**\*.csproj"
  />
</ItemGroup>

<MSBuild
  Projects="@(ALL_PROJECTS_IN_SOLUTION_EXCEPT_TESTS)"
  Properties="Platform=$(Platform);Configuration=$(Configuration)"
  BuildInParallel="true"
/>

然而,这会导致我们所有的 .csproj 出现以下错误:

The OutputPath property is not set for project [...].csproj

这很奇怪,因为 OutputPath 是在我们的 .csproj 文件中定义的(如上所示)。

如果我们指定“输出”属性,那么问题当然会消失,但是我们真正想要的是这些项目将自己输出到它们各自适当的输出目录中(如上所示)。如何实现这一目标?

4

1 回答 1

1

看起来您有一个单独的项目(构建项目)用于构建 .Common .csproj 和 .Utils .csproj 项目。并且您上面编写的脚本是在 Build Project 中的一个目标中定义的。(希望我没有误会。)

根据您的错误消息The OutputPath property is not set...Common 中没有定义 OutputPath 属性。.csproj 或 Utils。.csproj。

如果是这样,我建议您使用这样的文件夹结构:

Solution.sln
  \- VirtualFolder1
       \- Foo.Common.Bar.csproj -> Foo.Common.Bar\bin
       \- Foo.Common.Ping.csproj -> Foo.Common.Ping\bin
       \- Foo.Common.Pong.csproj -> Foo.Common.Pong\bin
  \- VirtualFolder2
       \- Foo.Utils.Bar.csproj -> Foo.Utils.Bar\bin
       \- Foo.Utils.Ping.csproj -> Foo.Utils.Ping\bin
       \- Foo.Utils.Pong.csproj -> Foo.Utils.Pong\bin

因为要获得您想要的相同结构,我认为可能还有更复杂的工作:

1.在.csproj文件中没有OutputPath的情况下,我们可以在其路径上方的Directory中创建一个Directory.Build.props文件来控制输出路径。

2.在您的 MSBuild 任务中传递 OutputPath 属性。在这种情况下,您需要获取 .common.csproj 和 .utils.csproj 项目的第二个名称并添加如下条件:

<MSBuild
      Projects="@(ALL_PROJECTS_IN_SOLUTION_EXCEPT_TESTS)"
      Properties="Platform=$(Platform);Configuration=$(Configuration);OutputPath=xxx\ThirdName\bin"
      BuildInParallel="true"
      Condition="judge if the common.csproj files"
    />
    <MSBuild
      Projects="@(ALL_PROJECTS_IN_SOLUTION_EXCEPT_TESTS)" 
      Properties="Platform=$(Platform);Configuration=$(Configuration);OutputPath=xxx\SecondName.ThirdName\bin"
      BuildInParallel="true"
      Condition="judge if the utils.csproj files"
    />

因此,这两个方向都可能有助于实现您的特定目标,但工作量会比我们预期的要多得多。

作为一种解决方法: 您必须将它们放在Utils.Bar\bin文件夹而不是Foo.Utils.Bar\bin文件夹中的原因是什么?后者是 Foo.Utils.Bar.csproj 文件的预定义属性。所以我们可以很容易地使用 $(ProjectDir) 或 $(ProjectName) 来表示它。您可以创建一个 Directory.Build.props 文件,添加以下脚本:

<Project>
 <PropertyGroup>
  <OutputPath>$(ProjectDir)bin\$(Configuration)</OutputPath>
</PropertyGroup>
</Project>

这样,在 VS 中加载项目文件时,需要做的是build the solution. 您将不再需要构建 Build 项目。而且由于您使用的是我没有尝试过的虚拟路径,也许您可​​以使用<OutputPath>AbsolutePathOfMyOutput\$(ProjectName)bin\$(Configuration)</OutputPath>

更新:(直到今天才注意到您的编辑。)

根据您的编辑,您已在 .csproj 中设置了输出路径。

这里有两个建议:

1.如果您在VS ID中构建它们:每次在VS IDE之外通过记事本或什么对xx.csproj进行一些修改后,我建议您unload and reload the project file在构建它们之前右键单击项目

2.请检查您收到的整个错误消息是否如下所示:

error : The OutputPath property is not set for project 'ConsoleApp1.csproj'.  Please check to make sure that
 you have specified a valid combination of Configuration and Platform for this project.  Configuration=''  Platform='An
yCPU'.

由于你是在for和.IfOutputPath property中定义的,如果你没有将相应的参数传递给 msbuild.exe,那么进程就无法从这些 ProppertyGroups 中读取 OutPutPath 属性。PropertyGroupDebug|AnyCPURelease|AnyCPU

例如:您在Debug|AnyCPU和中定义 OutPutPath Release|AnyCPUConfiguration and Platform那么你传递的真正值是Debug|X86, or Null|AnyCPU or CustomDebug|AnyCPU,而你没有OutPutPath在这种组合(PropertyGroup)中定义,你会得到错误消息xxx not set

要解决这个问题:确保您通过正确的配置和平台组合可以解决它。或者在您实际使用的组合中定义 OutPutPath。

于 2019-06-19T04:16:45.507 回答