MSBuild ignores its own ShowTimestamp parameter - msbuild

The reference for the command line arguments (http://msdn.microsoft.com/en-us/library/ms164311%28v=vs.100%29.aspx) shows that for console and file logger there is a parameter called ShowTimestamp which prefixes messages with a timestamp.
How does this work? Reproduction file:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<Target Name="Build">
<Message Text="Message" />
</Target>
</Project>
Call:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /clp:ShowTimestamp;ShowEventId dummy.msbuild.xml
I can see the ShowEventId displayed in the output but the timestamp is missing. I've tried this for /flp as well, no timestamp.
I tried other params like PerformanceSummary etc, all fine. I tried setting tool version to 12.0, same result.

Using reflector I realized that ShowTimestamp is used only inside ParallelConsoleLogger class, so the only way to see timestamp (without writing own logger) is to to force msbuild to use parallel logger, i.e. we need to specify /m switch.
Resulting command line for your sample will be
msbuild.exe /clp:ShowTimestamp;ShowEventId /m dummy.msbuild.xml
If computer has single core (like, virtual build machine), then /m will work like /m:1 and will use simple logger, but you can work around this by specifying /m:2 for example - it will still use the only available core, BUT it will use ParallelConsoleLogger.

Related

.NET-Core: Running the built application in PostBuildEvent

I have an Exe project that I would like to run in the PostBuildEvent block. I have tried adding a command to do this several ways but nothing seems to work.
dotnet run -- -i
dotnet run TestConsole.csproj -- -i
dotnet run ../../../TestConsole.csproj -- -i
../../../init.bat (which contains a cd to the project directory and "dotnet run...")
The first two fail being unable to find anything to run. The last two fail by hanging. Apparently, dotnet build recursively calling dotnet run doesn't work very well.
Is there a way of doing this?
The easiest way to do this is to re-use the built-in targets that already calculate the command. dotnet run also builds the project, so calling dotnet run could cause an infinite recursion - instead it should be dotnet path/to/the.dll. Also, PostBuildEvent is considered deprecated and has problems in SDK-based projects (an upcoming VS update will add targets instead when adding post build commands).
To execute the program on build, you can add the following to the csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<!-- other project content -->
<Target Name="RunAfterBuild" AfterTargets="Build">
<Exec Command="$(RunCommand) $(RunArguments)" WorkingDirectory="$(RunWorkingDirectory)" />
</Target>
</Project>
The AfterTargets="Build" will cause to to run after ever build, even if it is invoked through VS. If it should not be run when working on the project in VS, you could add
Condition=" '$(BuildingInsideVisualStudio)' != 'true' "
as an attribute to the <Target> element.
The values for $(RunCommand), $(RunArguments) and $(RunWorkingDirectory) are defaulted by the SDK and contain the right paths to the host / exe file etc. involved. You can add any custom parameters to the Command="..." attribute and they will be passed to the application (no -- needed).
In order to add global arguments that would also be respected when the project was built/run through dotnet run, the StartArguments property in the project can be set. it will be added to RunArguments automatically:
<Project …>
<PropertyGroup>
<StartArguments>--sample-option</StartArguments>
</PropertyGroup>
<!-- other content -->
</Project>

Full list of /P MSDeploy arguments for MSBuild from TeamCity

I currently use the MSBuild runner in TeamCity for continuous integration on my local server and this works very well. However, I'm having trouble finding a full list of supported command line switches for MSDeploy in the format that TeamCity expects them.
In my 'Parameters' section at the moment I using the following switches:
/P:Configuration=OnCommit
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=https://CIServer:8172/MsDeploy.axd
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True
/P:UserName=Kaine
/P:Password=**********
/P:DeployIISAppPath="OnCommit/MySite"
/P:SkipExtraFilesOnServer=True
/P:DeployAsIisApp=True
All of these seem to work fine and the MSDeploy works as expected.
The trouble comes when I want to add additional parameters.
I've looked up MSBuild parameters and the MSDeploy documentation and I only seem to find command line parameters like these:
msbuild SlnFolders.sln /t:NotInSolutionfolder:Rebuild;NewFolder\InSolutionFolder:Clean
http://msdn.microsoft.com/en-us/library/ms164311.aspx
It seems that these references for command line arguments don't correspond with the /P: format - for example CreatePackageOnPublish and DeployIISAppPath aren't recognised command line parameters, but they work fine in the TeamCity build process.
Where can I find a full documented list of MSDeploy arguments in the format
/P:Param=Value
Additional info:
There's a list of parameters here:
http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.workflow.activities.msbuild_properties.aspx
However this is not a complete list - for example, this list doesn't include DeployAsIisApp or SkipExtraFilesOnServer, which are both parameters that work from the Team City Build.
Also this related question (possibly duplicate): Valid Parameters for MSDeploy via MSBuild which contains some arguments - but still not a definitive list.
Firstly, the short answer is you can't find the complete list. MSBuild does not have a complete list of parameters you can chose from since you can send any parameter you like. It is a means of communication between the caller of MSBuild and the author of the MSBuild build script (a vs sln or csproj file for instance).
If the build script use the parameter it is used otherwise it is ignored.
So this is a valid call to msbuild:
msbuild /p:<anything>=<anything>
Secondly, you shouldn't send parameters to msbuild from teamcity using the /p: command options. Instead, set configuration or system properties in your teamcity build configuration. They will be passed to msbuild automatically as parameters.
Here are the parameters used by Visual Studio Team Services when creating an ASP.NET (Preview) build definition:
/p:DeployOnBuild=true
/p:WebPublishMethod=Package
/p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true
/p:PackageLocation="$(build.artifactstagingdirectory)\\"
One may also extrapolate from the <PropertyGroup /> blocks defined in these examples:
https://msdn.microsoft.com/en-us/library/ff398069(v=vs.110).aspx
From this example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>Package</WebPublishMethod>
<LaunchASiteUrlAfterPublish>False</LaunchASiteUrlAfterPublish>
<SiteUrlToLaunchAfterPublish />
<MSDeployServiceURL />
<DeployIisAppPath />
<RemoteSitePhysicalPath />
<AllowUntrustedCertificate>False</AllowUntrustedCertificate>
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<DeployAsIisApp>True</DeployAsIisApp>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<UserName />
<SavePWD>True</SavePWD>
<PublishDatabaseSettings>
<!— this section omitted to keep the example short -->
</PublishDatabaseSettings>
</PropertyGroup>
</Project>
You could derive the following list:
WebPublishMethod
LaunchASiteUrlAfterPublish
SiteUrlToLaunchAfterPublish
MSDeployServiceURL
DeployIisAppPath
RemoteSitePhysicalPath
AllowUntrustedCertificate
SkipExtraFilesOnServer
DeployAsIisApp
MSDeployPublishMethod
UserName
SavePWD
PublishDatabaseSettings

How make MSBuild build custom target specified in csproj building sln?

I am facing an issue with MSBuild I can't overcome it by myself. As a result I rely on community's wisdom.
The real situation I'm having troubles with
I have a soluiton file containing several projects with dependencies to other projects in same solution. I'd like to append a custom target to one of the project's csproj file and build it from the command line. It will allow me to make all the necessary output binaries for this project for further processing during the building of the custom target. But the main thing is that I can't figure out how to do it, googling doesn't help either.
Simplification
To make thing simplier I decided to make a new C# console project, add a simple custom target to the project's file and try to make it build. Still no success! Here what I've done so far:
Created a solution app with a default console project coreapp. This gaves me at least two files:
app.sln
coreapp\coreapp.csproj
Modified coreapp.csproj with addition of my custom target inside of the Project tag
<Target Name="SampleTarget">
<Message Text="This is a SampleTarget" />
</Target>
Run on the command line the following command
%windir%\Microsoft.NET\framework\v3.5\msbuild.exe app.sln /t:coreapp:SampleTarget
or even
%windir%\Microsoft.NET\framework\v3.5\msbuild.exe app.sln /t:coreapp.csproj:SampleTarget
Results
No luck, facing the error
MSB4057: The target "coreapp.csproj:SampleTarget" does not exist in the project.
I suspect that MSBuild thinks somehting fundamentally different from what I want it to think...
BEsides that, I also tried to set on the same command line the environment variable MSBuildEmitSolution=1 to force msbuild dump a temporary solution file it creates while processing the solution. In this file, indeed, no such target. However I guess it isn't the reason because I asked msbuild to build coreapp.proj where target SampleTarget really resides.
The question is how to build SampleTarget in this simplified scenario using solution file since potencially it can contain dependencies for the project containing this SampleTarget target?
I'd be greatful for any sort of help or firection for further investigation!
Instead of inserting a custom target in your project file, you could try creating a new standalone msbuild file, which would:
build the solution file (which builds projects)
defines your extra target
Call it app-custom-Debug.msbuild , for example.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WorkingFolder>$(MSBuildProjectDirectory)</WorkingFolder>
<Configuration>Debug</Configuration>
<SolutionFile>app.sln</SolutionFile>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="Compile" />
<Target Name="Compile">
<Message Text="=== COMPILING $(Configuration) configuration ===" />
<MSBuild Projects="$(SolutionFile)"
Properties="Configuration=$(Configuration)" />
</Target>
<Target Name="SampleTarget">
<Message Text="This is a SampleTarget" />
</Target>
</Project>
Then you execute:
msbuild.exe app-custom-Debug.msbuild /t:SampleTarget
One option is to tie your SampleTarget to the standard Build targets via overriding the appropriate DependsOn property. In this case you could tell BeforeBuild that it DependsOn SampleTarget or you do the same thing with AfterBuild. This will ensure that MSBuild processes your target prior to the standard target indicated.

Preventing MSBuild from building a project in a .sln without using Solution Configurations

I want to inhibit the building of certain projects within a solution from building (within a TeamCity Build Configuration in order to optimize the speed of my Commit Build feedback if you must know).
I'm aware of the Solution Configurations mechanism but don't want to have to force lots of .sln files to end up with every permutation of things I want to be able to switch off. I have Convention based rule where I want to say "If I'm doing the Commit Build, I dont want to do the final installer packaging". (And I don't want to break it out into a separate solution).
I'd prefer not to use a solution involving find and replace in the .sln file or in a .proj file created via [MsBuildEmitSolution][1]. I'm aware of questions here which cover the out of the box solution and this slightly related question.
I see MSBuild /v:diag is saying:
2>Target "Build" in file "Z.sln.metaproj" from project "Z.sln" (entry point):
Using "MSBuild" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "MSBuild"
Global Properties:
BuildingSolutionFile=true
CurrentSolutionConfigurationContents=<SolutionConfiguration>
<ProjectConfiguration Project="{C83D035D-169B-4023-9BEE-1790C9FE22AB}" AbsolutePath="X.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{15E7887D-F1DB-4D85-8454-E4EF5CBDE6D5}" AbsolutePath="Y.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
</SolutionConfiguration>
So the question is:
Is there a neat way of me getting to do an XPath replace or similar to have the effect of changing BuildProjectInSolution="True" to BuildProjectInSolution="False" for Project Y above
Failing that, is there a relatively simple edit I can do within a .ccproj (An Azure 1.4 Package) or a .csproj (a general project) file to cause the effects (including triggering of dependent projects) of the project being enabled within a commandline msbuild Z.sln solution build to be nullified?
Not sure it qualifies as neat, but you can set CustomAfterMicrosoftCommonTargets to import an msbuild file to over-ride the BuildDependsOn property, pointing it to your own custom build task. Basically, by setting CustomAfterMicrosoftCommonTargets you get msbuild to import an msbuild file containing the following:
<PropertyGroup>
<OldBuildDependsOn>$(BuildDependsOn)</OldBuildDependsOn>
<BuildDependsOn>MyBuild</BuildDependsOn>
</PropertyGroup>
<Target Name="OldBuild" DependsOnTargets="$(OldBuildDependsOn)" />
<Target Name="MyBuild">
<CallTarget Targets="OldBuild" Condition="<IfIWantThis>" />
</Target>
Edit
You can use the following MyBuild target to Include/Exclude projects based on regular expressions passed in as IncludeInBuild and ExcludeFromBuild properties. (If you want complex regexes, you may fall foul of MSBuild special character escaping, but this works well enough for simple matching)
> msbuild /p:ExcludeFromBuild="Tests|Install|Azure"
<Target Name="MyBuild">
<CallTarget Targets="OldBuild" Condition="('$(IncludeInBuild)'=='' OR
'$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
$(IncludeInBuild),
System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='True') AND
('$(ExcludeFromBuild)'=='' OR
'$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
$(ExcludeFromBuild),
System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='False')" />
</Target>
You could always pass the particular projects you want to build as parameters to the MSBuild.
The MSBuild command line would look like this:
MSBuild /t:<Project Name>:Rebuild;<Another Project Name>:Rebuild
In TeamCity, you would put <Project Name>:<Target Action> in the target field in the MSBuild runner.
I add a system parameter under Parameters
Name: system.ExcludeFromBuild
Kind: System property (system.)
Value: path to your csproj

Is there a way not to let MsBuild run static contract analysis with code contracts?

In my project, static checking is disabled, but still, when I run msbuild.exe with cmd, it starts static checking for each project... Is there a way, with parameters, to disable this?
This might be a 'little' late, but since I just encountered the same problem and /p:RunCodeAnalysis=false doesn't work for me:
Try msbuild ... /p:CodeContractsRunCodeAnalysis=false.
That works as of Feb. 2011 according to the code contracts documentation and my experience.
The following should do it:
MSBuild ... /p:RunCodeAnalysis=false
If you don't want to pass parameters to msbuild or you are building from Visual Studio, there is a way to suppress static code contracts check and code analysis.
Notice: each *.csproj file contains this: <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />.
For .Net 4.0 msbuild.exe and Microsoft.CSharp.targets path is "C:\Windows\Microsoft.NET\Framework\v4.0.30319\"
Open Microsoft.CSharp.targets
Add new PropertyGroup inside Project like:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<PropertyGroup>
<CodeContractsRunCodeAnalysis>false</CodeContractsRunCodeAnalysis>
<RunCodeAnalysis>Never</RunCodeAnalysis>
<CodeContractsReferenceAssembly>DoNotBuild</CodeContractsReferenceAssembly>
</PropertyGroup>
...
<!-- a lot of stuff -->
...
</Project>
Doing so will emulate msbuild command line arguments (i.e /p:CodeContractsRunCodeAnalysis=false,RunCodeAnalysis=Never,CodeContractsReferenceAssembly=DoNotBuild
All your builds now on your pc (either from MSBuild and Visual Studio) will skip code and static code contracts analysis, so you don't need to pass args from Command Line.