We have a solution created and maintained via VisualStudio2017 in which our .csprojs are placed inside virtual-folders like so:
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
As expected each and every .csproj file already contains a section which defines where the output path should be:
<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>
We want to build all .Common .csproj and .Utils .csproj projects en-masse into their respective output folders without having to specify them in our msbuild-script (which is invoked by JenkinsCI btw) one by one. To achieve that we have tried:
<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"
/>
This however results in the following errors for all our .csproj:
The OutputPath property is not set for project [...].csproj
This is strange given the fact that the OutputPath is defined in our .csproj files (as shown above).
If we specify the 'Output' property then the problem goes away of course however what we really want is these projects to output themselves into their respective appropriate output directories (shown above). How can one go about achieving this?
Looks like you have one separate project(Build Project) used to build the .Common .csproj and .Utils .csproj projects. And the script you write above is defined in a target in the Build Project. (Hope I didn't misunderstand.)
According to your error message
The OutputPath property is not set...
There is no OutputPath property defined in the Common..csproj or Utils..csproj.If so, I suggest you use a folder structure like this:
Because to get the same structure you want I think maybe there has much more complex work:
1.With no OutputPath in .csproj file, we can create a Directory.Build.props file in the Directory above its path to control the output path.
2.Pass the OutputPath property in your MSBuild Task. In this situation you need to get the second name for .common.csproj and .utils.csproj projects and add conditions like:
So both of these two directions may help achieve your particular goal, but the work would be much more than we expect.
As a workaround: What's reason you must put them in
Utils.Bar\bin
folder instead ofFoo.Utils.Bar\bin
folder? The latter one is pre-defined property for the Foo.Utils.Bar.csproj file. SO we can easily use the $(ProjectDir) or $(ProjectName) to represent it. You can Create a Directory.Build.props file, add the script below:In this way, when loading the project files in VS, what you need to do is to
build the solution
. You won't need to build the Build project any more. And since you're using the virtual-path which I haven't tried, maybe you can use<OutputPath>AbsolutePathOfMyOutput\$(ProjectName)bin\$(Configuration)</OutputPath>
Update:(Haven't noticed your edit until today.)
According to your edit, you've set the output path in the .csproj.
Here are two suggestions:
1.If you build them in VS ID: Every time after you do some modify to xx.csproj outside VS IDE by notepad or what, I suggest you right-click the project to
unload and reload the project file
before you build them2.Please check if the entire error message you get looks like this:
Since your
OutputPath property
are defined inPropertyGroup
forDebug|AnyCPU
andRelease|AnyCPU
.If you haven't passed the corresponding parameters to msbuild.exe, the process can't read the OutPutPath property from these ProppertyGroups.For example: You define the OutPutPath in
Debug|AnyCPU
andRelease|AnyCPU
. Then the real value ofConfiguration and Platform
you pass isDebug|X86, or Null|AnyCPU or CustomDebug|AnyCPU
, and you haven't definedOutPutPath
in this kind of Combination(PropertyGroup), you'll get the error messgaexxx not set
.To resolve this: Make sure you pass the correct Configuration and Platform combination can resolve it. Or define OutPutPath in the Combination you actually use.