Property Page XML rule files (original) (raw)

The project property pages in the IDE are configured by XML files in the default rules folder. The XML files describe the names of the rules, the categories, and the individual properties, their data type, default values, and how to display them. When you set a property in the IDE, the new value is stored in the project file.

The path to the default rules folder depends on the locale and the version of Visual Studio in use. In a Visual Studio 2015 or earlier developer command prompt, the rules folder is %ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\<version>\<locale>. The <version> value is v140 in Visual Studio 2015. The <locale> is an LCID, for example, 1033 for English. You'll use a different path for each edition of Visual Studio that's installed, and for each language. For example, the default rules folder path for Visual Studio 2015 Community edition in English could be C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\v140\1033\.

The path to the default rules folder depends on the locale and the version of Visual Studio in use. In a Visual Studio 2017 developer command prompt, the rules folder is %VSINSTALLDIR%Common7\IDE\VC\VCTargets\<locale>\. The <locale> is an LCID, for example, 1033 for English. In a Visual Studio 2015 or earlier developer command prompt, the rules folder is %ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\<version>\<locale>\, where the <version> value is v140 in Visual Studio 2015. You'll use a different path for each edition of Visual Studio that's installed, and for each language. For example, the default rules folder path for Visual Studio 2017 Community edition in English could be C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\1033\.

The path to the default rules folder depends on the locale and the version of Visual Studio in use. In a Visual Studio 2019 or later developer command prompt, the rules folder is %VSINSTALLDIR%MSBuild\Microsoft\VC\<version>\<locale>\, where the <version> value is v160 in Visual Studio 2019. The <locale> is an LCID, for example, 1033 for English. In Visual Studio 2017, the rules folder is %VSINSTALLDIR%Common7\IDE\VC\VCTargets\<locale>\. In a Visual Studio 2015 or earlier developer command prompt, the rules folder is %ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\<version>\<locale>\. You'll use a different path for each edition of Visual Studio that's installed, and for each language. For example, the default rules folder path for Visual Studio 2019 Community edition in English could be C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\1033\.

You only need to understand the internal workings of these files and the Visual Studio IDE in a couple of scenarios:

Contents of rule files

First, let's open the property pages for a project. Right-click on the project node in Solution Explorer and choose Properties:

Screenshot of the project Property Pages dialog.

Each node under Configuration Properties is called a rule. A rule sometimes represents a single tool like the compiler. In general, the term refers to something that has properties, that executes and that may produce some output. Each rule is populated from an XML file in the default rules folder. For example, the C/C++ rule that's shown here is populated by cl.xml.

Each rule has a set of properties, which are organized into categories. Each sub-node under a rule represents a category. For example, the Optimization node under C/C++ contains all the optimization-related properties of the compiler tool. The properties and their values get rendered in a grid format on the right pane.

You can open cl.xml in notepad or any XML editor. You'll see a root node called Rule. It defines the same list of properties that get displayed in the UI, along with additional metadata.

<?xml version="1.0" encoding="utf-8"?>
<!--Copyright, Microsoft Corporation, All rights reserved.-->
<Rule Name="CL" PageTemplate="tool" DisplayName="C/C++" SwitchPrefix="/" Order="10" xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Rule.Categories>
    <Category Name="General" DisplayName="General" />
    <Category Name="Optimization" DisplayName="Optimization" />
    <Category Name="Preprocessor" DisplayName="Preprocessor" />
    <Category Name="Code Generation" DisplayName="Code Generation" />
    <Category Name="Language" DisplayName="Language" />
    <Category Name="Precompiled Headers" DisplayName="Precompiled Headers" />
    <Category Name="Output Files" DisplayName="Output Files" />
    <Category Name="Browse Information" DisplayName="Browse Information" />
    <Category Name="Advanced" DisplayName="Advanced" />
    <Category Name="All Options" DisplayName="All Options" Subtype="Search" />
    <Category Name="Command Line" DisplayName="Command Line" Subtype="CommandLine" />
  </Rule.Categories>
  <!-- . . . -->
</Rule>

There's one XML file for every node under Configuration Properties in the property pages UI. You can add or remove rules in the UI: it's done by including or removing locations to corresponding XML files in the project. For example, it's how Microsoft.CppBuild.targets (found one level higher than the 1033 folder) includes cl.xml:

<PropertyPageSchema Condition="'$(ConfigurationType)' != 'Utility'" Include="$(VCTargetsPath)$(LangID)\cl.xml"/>

If you strip cl.xml of all data, you have this basic framework:

<?xml version="1.0" encoding="utf-8"?>
<Rule>
  <Rule.DataSource />
  <Rule.Categories>
    <Category />
    <!-- . . . -->
  </Rule.Categories>
  <BoolProperty />
  <EnumProperty />
  <IntProperty />
  <StringProperty />
  <StringListProperty />
</Rule>

The next section describes each major element and some of the metadata that you can attach.

Rule attributes

A <Rule> element is the root node in the XML file. It can have many attributes:

<Rule Name="CL" PageTemplate="tool" SwitchPrefix="/" Order="10"
          xmlns="http://schemas.microsoft.com/build/2009/properties"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Rule.DisplayName>
    <sys:String>C/C++</sys:String>
  </Rule.DisplayName>
<DataSource Persistence="ProjectFile" ItemType="ClCompile" Label="" HasConfigurationCondition="true" />  
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">  
  <ClCompile>  
    <TreatWarningAsError>true</TreatWarningAsError>  
  </ClCompile>  
</ItemDefinitionGroup>  

If this value is set in the property page for a specific file, such as stdafx.cpp, then the property value should be written under the stdafx.cpp item in the project file as shown Here. Notice how the configuration condition is directly attached to the metadata itself:

<ItemGroup>  
  <ClCompile Include="stdafx.cpp">  
    <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>  
  </ClCompile>  
</ItemGroup>  

Another attribute of DataSource not listed here is PersistedName. You can use this attribute to represent a property in the project file using a different name. By default, this attribute is set to the property's Name.
An individual property can override the DataSource of its parent Rule. In that case, the location for that property's value will be different from other properties in the Rule.

Category elements

A Rule can have multiple Category elements. The order in which the categories are listed in the XML file is a suggestion to the UI to display the categories in the same order. For example, the order of the categories under the C/C++ node you see in the UI is the same as the order in cl.xml. A sample category looks like this:

<Category Name="Optimization">
  <Category.DisplayName>
    <sys:String>Optimization</sys:String>
  </Category.DisplayName>
</Category>

This snippet shows the Name and DisplayName attributes that have been described before. Once again, there are other attributes a Category can have that aren't shown in the example. You can learn about them by reading the documentation or by examining the assemblies using ildasm.exe.

Property elements

Most of the rule file consists of Property elements. They contain the list of all properties in a Rule. Each property can be one of the five possible types shown in the basic framework: BoolProperty, EnumProperty, IntProperty, StringProperty, and StringListProperty. You might have only a few of those types in your file. A property has a number of attributes that allow it to be described in detail. The StringProperty is described here. The rest are similar.

<StringProperty Subtype="file" Name="ObjectFileName" Category="Output Files" Switch="Fo">
  <StringProperty.DisplayName>
    <sys:String>Object File Name</sys:String>
  </StringProperty.DisplayName>
  <StringProperty.Description>
    <sys:String>Specifies a name to override the default object file name; can be file or directory name.(/Fo[name])</sys:String>
  </StringProperty.Description>
</StringProperty>

Most of the attributes in the snippet have been described before. The new ones are Subtype, Category, and Switch.