Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MsBuild condition for new ("sdk-style") vs. old project format

I want to write an msbuild "include" (.props) file that is to be imported in both the new ("sdk-style") projects as well as the old ones.

Is there a way to find out into which type of project the .props file is imported so I could use that in a condition? For example,

<PropertyGroup Condition="'$(ProjectType)'=='sdk'">
   <SomeProperty>SomeValue</SomeProperty>
</PropertyGroup>
like image 565
wexman Avatar asked Sep 19 '18 07:09

wexman


People also ask

What is SDK-style project?

Each project SDK is a set of MSBuild targets and associated tasks that are responsible for compiling, packing, and publishing code. A project that references a project SDK is sometimes referred to as an SDK-style project.

How does Visual Studio determine project type?

If you are working in Visual Studio, you can quickly check the project format using one of the following methods: Right-click the project in Solution Explorer and select Edit myprojectname. csproj. This option is only available starting in Visual Studio 2017 for projects that use the SDK-style attribute.

Which is the initial step needed when using the MSBuild at the command prompt?

Build the targettargets file. Run MSBuild from the Developer Command Prompt for Visual Studio to build the HelloWorld target defined above. Use the -target or -t command-line switch to select the target.

How do I set properties in MSBuild?

MSBuild lets you set properties on the command line by using the -property (or -p) switch. These global property values override property values that are set in the project file. This includes environment properties, but does not include reserved properties, which cannot be changed.


2 Answers

I encountered this same need in my project. At first I went with the solution @wexman, but I found that variable not to be reliable. I considered the approach of opening the csproj file and using regexes to look for the SDK attribute, but it felt too brittle to me - especially given that the SDK can be specified either in an element or an attribute. Finally I created a build with binary logging turned on (option /bl) and went hunting through the various files that get imported when doing a build of an SDK-style project.

I discovered the property UsingMicrosoftNETSdk which is set to true in the props file which auto-imports Microsoft.Common.props when you are using an SDK-style project. This auto-import (which leads to the auto-import of Directory.Build.props seems to be one of the most important defining characteristics of SDK-style projects, and the name of the property makes it look like something more likely to stick around.

So in the end my solution was to have:

Condition="'$(UsingMicrosoftNETSdk)' == 'true'"

(or its inverse) as the reliable way to determine which type of project is in use.

like image 191
simmdan Avatar answered Oct 22 '22 18:10

simmdan


I seem to have found a working solution. I'm checking against the property $(_PlatformWithoutConfigurationInference) declared in Microsoft.NET.Sdk.Props. If it is not empty, I'll be dealing with an sdk style project, if it is empty, it's a legacy project:

<Project>

  <PropertyGroup>
    <ProjectStyle Condition="'$(_PlatformWithoutConfigurationInference)'!=''">sdk</ProjectStyle>
    <ProjectStyle Condition="'$(_PlatformWithoutConfigurationInference)'==''">legacy</ProjectStyle>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Message Importance="High" Text="$(MsBuildProjectName) is a $(ProjectStyle) style project" />
  </Target>

</Project>
like image 45
wexman Avatar answered Oct 22 '22 18:10

wexman