How can I know which properties are applicable for MSBuild? - msbuild

From here, I get to know how to create a Web Deployment Package with MSBuild. The command line looks like this:
MSBuild "MyProjectName.csproj" /T:Package /P:Configuration=Staging;PackageLocation="D:\Vishal\Package.zip"
The Configuration, PackageLocation are both properties.
I just wonder how can I know which properties are applicable? And their formal definitions?
I searched the MSBuild Reserved and Well-Known Properties, but they are not there.
And I searched the MSBuild Task, still no luck.
ADD
It seems different project types have their specific properties. For example, the PackageLocation property should be specific to a Web Application project. What I am looking for is the specific definition of these properties.
ADD 2
I have a MSBuild task as below.
> <MSBuild Targets="Clean; Package"
> Projects="$(XXXSolutionDirectory)\Web\Web.csproj"
> Properties="Configuration=$(Configuration); Platform=$(Platform);
> OutputPath=$(BinDirectory)\Web_Deployment_Package;
> PackageLocation=$(BinDirectory)\Web_Deployment_Package;
> PublishDir=$(BinDirectory); OutDir=$(BinDirectory);
> IntDir=$(IntDirectory); TfsBuild=$(TfsBuild);
> CscToolPath=$(CscToolPath); CscToolExe=$(CscToolExe);
> VbcToolPath=$(VbcToolPath); VbcToolExe=$(VbcToolExe);
> TargetProfile=$(XXXConfiguration)"></MSBuild>
The properties such as PackageLocation are placed within the Properties attribute of MSBuild task. Rather than in a PropertyGroup definition. And this is the only place it shows up in the build proj file. So where can I find its definition to understand its intended usage?

Ok, let's start first with the bit of fundamental processing pipeline of MSBuild.
When msbuild engine parses your proj file - it takes all
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.CSharp.targets
around line 379 you can see
<Import Project="Microsoft.Common.targets" />
this means - in the final big script - instead of line 379 you'll see the content of
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets
then in the next phase - msbuild will calculate all Global Properties and Items values.
It has some rules on which value (because you may have multiple property declarations with different values which will end up in a property with single value - usually last one or global one wins) will be assigned to property, but I'll omit these details here.
And the properties you specified in msbuild command line also participating in this process.
Particular property declaration can be in more than one .targets file but that really doesn't matter. What's matter is - what value this property will have at the end of global property processing phase.
But if you really want to know where is particular property is defined - you need to manually search through all imported .targets files and find property declaration tag.
Targets files can be in your .NET Fw folder or in installed SDKs (if you have specific project types like Azure .ccproj ones)
For example - let's take most popular property "Configuration".
I sought in all .targets files text <Configuration and Microsoft.Common.targets line 132 has this entry:
<Configuration Condition=" '$(Configuration)'=='' ">Debug</Configuration>
As you can see - there is a condition which is saying - set configuration to Debug if it's not yet defined.
Because you specified this property's value as a command line parameter - your property will have higher priority and will cause this condition to be false, thus your value will be the final value of this particular property.
Same for PublishDir - Microsoft.Common.targets line 425:
<!-- Output location for publish target. -->
<PropertyGroup>
<PublishDir Condition="'$(PublishDir)' != '' and !HasTrailingSlash('$(PublishDir)')">$(PublishDir)\</PublishDir>
<PublishDir Condition="'$(PublishDir)'==''">$(OutputPath)app.publish\</PublishDir>
</PropertyGroup>
and so on.
Some properties (especially for custom project types ) can be defined in it's own SDK .targets files, but if you'll open that custom .zzProj file and may find project properties there OR you can manually follow all <import directives - and eventually will find where every specific property is defined. And usually along with definition - you can trace how this property is being used by targets (search for $(MyPropertyName) ) and tasks, thus - alter it for your own needs or spot bugs or weird usages.
Hope this helps you.

First pre-process the MsBuild script to flatten and consolidate all imported scripts into a single MsBuild file.
MsBuild.exe MyProject.proj /pp >Output.xml
Now, open Output.xml in Notepad and search for instances of $(Configuration) and $(PackageLocation).
$(Configuration) is one of the base default properties you'd find in most MsBuild projects and you'd see it used in Microsoft.Common.CurrentVersion.Targets in targets that are designed to fail the build if an invalid or unexpected Platform or Configuration property is used.
PackageLocation is specific-to ASP.NET projects and the import taxonomy would include Microsoft.Web.Publishing.targets which contains several targets dedicated to parsing and validating that property as part of the web publication workflow.

Related

Expose MSBuild property in Cake script after build step

Can you get property set by MSBuild inside your cake script?
I currently have a target that runs after compilation to indicate whether it has run, or whether it was an incremental build.
I want to detect in the remainder of my cake build whether incremental build took place.
The target that I currently use on my MSBuild is as follows:
<!-- Defines Targets that should be run after Compile, but skipped if Compile doesn't take place -->
<PropertyGroup>
<TargetsTriggeredByCompilation>
$(TargetsTriggeredByCompilation);
EnablePostBuild
</TargetsTriggeredByCompilation>
</PropertyGroup>
<Target Name="EnablePostBuild">
<!-- Disable post build actions -->
<PropertyGroup>
<SkipPostBuildActions>false</SkipPostBuildActions>
</PropertyGroup>
</Target>
If I trigger the build in Cake as follows:
var buildSettings = new MSBuildSettings()
.WithProperty("SkipPostBuildActions", "true")
MSBuild("./src/Application.sln",buildSettings );
var SkipPostBuildActionsVal = buildSettings??
Can I get the value of SkipPostBuildActions after the MSBuild step?
This is actually not much of a Cake problem: Cake "only" runs msbuild using the given parameters.
So, if you find a way how to access a Property from outside msbuild you can transfer that solution to Cake.
AFAIK msbuild does not even support easy sharing of property-modifications between tasks, let alone outside the msbuild-process.
I see two possible solutions:
Output the value of SkipPostBuildActions into the log, using the Message-Task then set a FileLogger on your msbuild-call and parse the log-file afterwards.
Output the value of SkipPostBuildActions to a dedicated file using the WriteLinesToFile-Task then parse that file after msbuild has run.
Personally I'd chose the latter option.

Error in mule start up due to long properties file

I am facing one weird issue while running mule application. We have multiple entries in mule-app.properties (220 lines
). When I try to run the application, it fails with file or extension too error.
When I remove some random entries from properties file, application starts successfully. Any help will be appreciated.
I have had a similar issue to this, and it because of the way the entries in mule-app.properties are applied at runtime. The JVM is complaining that the VM arguments are too long, which is how properties in mule-app.properties are applied.
The way you can work-around it is to store your properties in a separate .properties file in src/main/resources and include this file as a property placeholder in your global configuration:
<context:property-placeholder location="myApp.properties"/>
Note if you use environment specific properties like this also you can reference multiple files separated with a comma, e.g.
<context:property-placeholder location="myApp.properties, ${mule.environment}.properties" />

TFS 2010: Perform different builds and command line task in sequence?

my build process with TFS 2010 should perform different task one after the other like:
Build 1st project in solution
Execute MSBuild via command line (to publish the project)
Execute a 3rd party tool via command line (to obfuscate the binaries)
Build a 2nd project in the solution (an InstallShield project)
How can I achieve this? I can define several project in the Build Definition but how can I invoke several command line task between these build steps? And the MSBuildArguments in the Build Definition: Are these arguments for every msbuild call for each project/solution?
Thanks
Konrad
At first, you need to add in your build definition the distinct *.*proj instead of one big *.sln - or (even better) construct more than one *.sln & order them to get build in the build definition. So you could organize a Project1.sln, Project2.sln etc that are only used from the Build.
In addition to that, you would have to make changes in the build process template to get this.By default you get something like that, that executes each set project/solution within a bigger foreach:
A good way would be to enhance this as a sequence, where all your custom action are set as InvokeProcess activities:
Obviously, you would have to insert here a flow control, so that Publish & Dotfuscator execute the first time (where Project1.sln gets build), while ISDEV executes the second time (where Project2.sln gets build). In the sample below I used a switch & packed Publish & Dotfuscator in a new Sequence.
Finally, you would have to have a counter of some sort. The most immediate option is to set a new Int32 Variable with default == 1 and increase it by hand during execution. In the sample below this is done in the lower Assign:
This final override of Complie the Project, along with a changed Build Definition should get what you 're after.
The team build definition takes a list of sln's and msbuild project files. You can put simply split your InstallShield project out into it's own solution ( most developers won't have a copy of InstallShield anyways likely ) and write an msbuild targets file for steps 2 and 3. Then just tell your build definition to build solution 1, the targets file and solution 2.
You could also choose to put the stuff in the targets file in a postbuild event for one of the projects in solution 1.
I wouldn't do this in workflow.

MSBuild: Task to embedding a file before compilation

I have the following need:
I'll have to create an MSBuild task that will produce an xml file, which I then need to embed as a resource to one of the projects being built. How do I change my MSBuild proj to accomplish that? Is there a built-in task I can use for embedding the file, or do I need to create one? If the latter, any direction on that would be great.
Thanks in advance!
Update: based on the suggestions given, I've ended up adding an empty xml file to the project as a resource, creating a simple MSBuild custom task (http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx) that writes content to that file as I need it, and running that task as a "BeforeBuild" target. Works like a charm. Note that I've had to "exclude the file from source control", so it won't get checked out every time I build the project, and I've also added some code to the task to make sure the file isn't read-only (http://www.del337ed.com/blog/index.php/2007/09/05/clearing-the-read-only-flag-on-a-file-in-c/).
If you don't need to create the whole Xml file from scratch and could add a stubb file to your project you could use the XmlPoke Task to update this file in the BeforeBuild Target (see Sergios answer).
You can use builtin in your .csproj/.vbproj file target BeforeBuild (not forget to uncomment it) and call required MSBuild task in BeforeTarget. In that project add that resource as embedded. That's all.

MSBuild not recognizing computer name in response file

We have a standard MSBuild project file that is used for our different deployment stages (pre-stage, stage, live, etc). Since each deployment stage is performed on a different server we introduced a server parameter called $SourceDatabaseServer and used this extensively in each of the targets inside the project file. Note: This database server name could be different from the server name on which the build is run.
To assist us with the customization of this parameter, we created a response file for each deployment stage and subsequently defined a value for this parameter in the response file, e.g. /p:SourceDatabaseServer=SRC_DB_NAME.
This worked fine, until we created a new deployment stage in which this value had to be the current computer name. So we thought by using the $(COMPUTERNAME) reserved property in the response file (/p:SourceDatabaseServer=$(COMPUTERNAME)), this would do the trick, but it seems like this value is interpreted literally by MSBuild, and we consequently get an error that server $(ComputerName) could not be found.
Interestingly, when the $(COMPUTERNAME) property is used directly in the proj file it works, but as stated above, we do not necessarily want to use the computer name in all the cases.
Is there a way to still use the $(COMPUTERNAME) property in the response file and get MSBuild to interpret this correctly?
What if you use %COMPUTERNAME%?
$(VAR) is the syntax for variable expansion when you're "inside" the MSBuild system, but coming from the outside, I believe you'd have to use the shell environment variable expansion syntax, %VAR%.