Reference for expression syntax in CSPROJ files - msbuild

Can somebody please point me to a reference for the syntax of the expression language used in csproj / vbproj files within Visual Studio ? I've been seeing usages like the following :
<FilesForPackagingFromProject Include="%(CustomFiles.Identity)">
... and I'm trying to understand the '.Identity' bit.

The Identity bit is one of many MSBuild Well-known Item Metadata. It is essentialy metadata of msbuild Items. You can use the metadata to Transform Item Types.

This question How do you include additional files using VS2010 web deployment packages? doesn't directly address your question but the most popular answer has loads of useful information and provides a clue as to what the % sign means.
<_CustomFiles Include="..\Extra Files\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
I think the _CustomFiles tag creates a link to an external file, then %(_CustomFiles.Identity) refers to an element within that external file.
UPDATE:
NO! This is not right. The % expression gives a scalar value. The _CustomFiles is an Item and the .Identity part of the syntax refers to well-known metadata as explained by Marcos in the accepted answer.

Related

Reference for msbuild itemgroup content

I several times had trouble finding information about valid elements in csproj files (.NET Core). Especially ItemGroup with Content and Include/Exclude/Update/CopyToPublishDirectory attributes.
Also I am interested in "None Include=..." elements.
Is there any offical reference for all this?
At least I could only find a few SO posts.
Update
in the meantime I found this upgrade guide (project.json -> csproj) by Nate McMaster which contains a few examples for Content and None but is far from a reference.
https://learn.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj
I have also had difficulty finding good reference information about this
This list of well known item metadata properties may help
https://msdn.microsoft.com/en-us/library/ms164313.aspx
However for include / exclude attributes (as against properties)
try this msdn link
https://msdn.microsoft.com/en-us/library/ms171453.aspx
At a pinch I have often written a custom task which takes an itemgroup and iterates metadata - though it's worth noting the difference between metadata (such as the Identity property), and attributes such as include exclude, which are fixed, and explained in the second msdn link

Setting MSBuild 'Condition' attribute via Visual Studio extension

I have a C# project which is built in a few different configurations. Some of the source files should be always included, and some only in certain configurations. So far I've been doing this with #if ... #endif around the entire files, but I was hoping to create a small extension to do this a nicer way.
I've created an extension that adds an item to files' context menus, but I can't find any way to set the Condition attribute on the item node in the project file.
I've looked at the Properties collection of the EnvDTE.ProjectItem interface, but can't see anything useful there (except BuildAction... I'll come back to that).
Then I tried getting an IVsBuildPropertyStorage on the item and calling SetItemAttribute(). This does add information to the project file, but as a child element like this:
<ItemGroup>
<Compile Include="Program.cs">
<Condition>%27%24%28Configuration%29%27==%27Debug%27</Condition>
</Compile>
</ItemGroup>
when what I was trying to achieve was:
<ItemGroup>
<Compile Include="Program.cs" Condition="'$(Configuration)'=='Debug'" />
</ItemGroup>
There's also an IVsBuildPropertyStorage.SetPropertyValue() but that adds a similar child element to a PropertyGroup section near the top, not to the item node.
I've looked at 'Project Subtypes/Flavors', but that looks like it's just going to get me another IVsBuildPropertyStorage, which doesn't seem to be useful. They do look capable of a lot of complex things, but documentation on the subject appears to be minimal and vague.
I've seen some posts describing how to use the MSBuild assemblies to directly load and manipulate the project file, but I'm not sure when is safe to do that without confusing Visual Studio and potentially losing changes, since VS prompts to reload when it detects changes to the project file.
As a last idea, I thought about manipulating the BuildAction property between Compile and None, but that sounds like it could be a lot of work for my extension to maintain correctly, keeping it in sync with every time the user switches configurations in the IDE for example.
Is there anyone with any experience with this kind of thing that has any advice to offer me, or should I give up hope and stick with manually adding #if directives everywhere?
You may like to explore the MSBuild option you mentioned.
You don't actually have to load the MSBuild project from file, because Visual Studio gives you a way of accessing the MSBuild project directly, i.e.:
string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
From there you can locate your specific items and potentially add the condition attribute, though I haven't tried this step myself (if this doesn't work, you might have to try modifying the project elements under the project.Xml property instead).
You can then call project.Save(), which shouldn't trigger the "Reload project?" dialog because of the way the MsBuild project instance is linked to the Visual Studio project hierarchy.
However, you may like to force Visual Studio to reload the project anyway, because if you switch build configurations (e.g. between Debug and Release), the MSBuild engine may not re-evaluate your item conditions during build. The code to do this programmatically can be found here:
How do I programmatically refresh/reload a VS project after modifying the underlying file?
Unfortunately I never got the time to persue the original goal of creating an extension for doing this, however I did achieve what I needed using the suggestion by lex-li: using separate project files per configuration.
Since the project files can all reside in the same directory, it's easy to simply use the 'Include/Exclude from project' context menu item in the solution explorer to choose which files are included. There's also no need for file linking this way, which I'd tried before and found very time-consuming to manage.
Partial Methods are also worth looking at, if you have similar needs. They allow you to define the signature of a method in one place, but optionally implement it elsewhere. If you don't implement it, no call is generated by the compiler.
With respect to the original idea of the extension, I suspect the answer by Daniel Nolan was heading in the right direction, but unfortunately I didn't get to try it out.

where is the reference for msbuild extensibility keywords?

I'm working with an msbuild file and I see things like %(copylocal) and #(intermediateassembly).
I know some of them can be found at http://msdn.microsoft.com/en-us/library/ms164313.aspx but is there a comprehensive list somewhere?
In general you can create your own properties (referenced with $) and items (referenced with #) with any metadata (referenced with %) you like. Take a look at this link and all related to her if you want to know more about main concepts of MSBuild: MSBuild Concepts

Msbuild properties

I have been recently sifting through MSBuild documentation trying to find other valid properties that can be passed to the task, and so far have been drawing up a blank on a centralized listing.
I believe that VCBuildAdditionalOptions & BuildCmd are both valid parameters, however does anybody know where there are any further valid properties listed?
Is this what you're looking for? Common MSBuild Project Properties
For TeamBuild, there's the WwW version and the Aaron Hallberg's Team Build 2008 Property Reference.

Where can I get a list of all the properties available in the project file?

I'm looking for a resource to list all the built-in properties defined in an MSBuild project file. Specifically I'm using a Team Build project file, but from what I understand they are one in the same (correct me if I'm wrong).
I already know about the reserved properties: http://msdn.microsoft.com/en-us/library/ms164309.aspx
But I've noticed other handy variables being referenced in examples, like $(SolutionRoot) and $(OutDir).
Is there a comprehensive list of all the properties I have access to? Where are these other properties defined? I found a forum post where the same question was asked, and it pointed to the Microsoft.TeamFoundation.Build.targets file, but I looked in there and could not find definitions for $(SolutionRoot) and $(OutDir) listed.
Thanks for any help you can give, Daniel
This is another great reference:
http://blogs.msdn.com/aaronhallberg/archive/2008/02/12/team-build-2008-property-reference.aspx
Vaccano
Did you see this: http://www.woodwardweb.com/vsts/30_useful_team.html