Debug msbuild custom task with msbuild v15.0 - msbuild

Microsoft's instructions for enabling debugging of MSBuild tasks no longer seem to work. I cannot get msbuild /? to show the /debug switch, and when I try dotnet publish /debug it complains that /debug is not a valid switch.
Is there any way to debug MSBuild tasks any more?

The /debug feature for msbuild was removed from public builds of MSBuild 15 and the code for it has later been removed entirely.
To "debug" logic in your build targets / msbuild files, your best option is to create binary logs using the -bl argument and inspecting them using the MSBuild Structured Log Viewer. It shows you all the inputs/outputs to task invocation and all the steps that happen during Msbuild runs.
Debugging custom tasks (e.g. C# code) is very hard to do. It would involve looping+sleeping until Debugger.IsAttached is true for debug builds (and then attaching to the process in Visual Studio) or calling Debugger.Launch() (only on .NET Framework, not .NET Core MSBuild).
I suggest separating the actual task class from your logic implementation to allow you to unit test your logic. This should remove the need to debug it during runs.
You can see a sample of both the debugger logic and the separation in NuGet's PackTask and its PackTaskLogic class.

Related

Stop SSDT being published when MSBuild publish run

I have a ClickOnce project that I'm publishing on DevOps. I've set the MSBuild Arguments property for the WinForm solution's build stage in DevOps to /target:Publish in order to trigger the creation of all the ClickOnce files:
However, that solution also contains an SSDT project, and adding the /target:Publish setting appears to then cause the build process to try publish the SSDT too. That then fails with the error:
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets(1808,5):
error MSB4044: The "SqlPublishTask" task was not given a value for the
required parameter "SqlPublishProfilePath"
Presumably it's failing because there's no publish profile specified in a build parameter for the SSDT to use.
I don't want MSBuild to publish the DacPac to a server, I just want it to create the DacPac. How can I stop the /target:Publish triggering the SSDT publish, is there another build argument I can add to stop that happening?
Notes on what I tried so far to solve this, none of which has worked:
Read about the -target switch in the MS Build official docs in the MSBuild command-line reference and in the MSBuild targets section.
Looked at the code in the .csproj file to try and identify the 'Publish' sections - think Publish must also call Build.
Unticking Deploy for the SSDTs in the solution configuration in VS
Adding entries for False in the Release and Deployment configurations in the SSDT's .csproj file, and also setting that to false for the Debug configuration (as per this question)
Setting MSBuild to only publish one project using the MS Build arguments on DevOps (as per this answer)
Considered pulling the ClickOnce publish out into an entirely separate stage using Mage.exe as per this Walkthrough: Manually deploy a ClickOnce application
Tried to create a publish profile that doesn't actually publish, so that the publish stage can complete (was looking at this question for ideas on that and also the official documentation for SqlPackage.exe)
Eventually I solved the issue above a completely different way. Instead of getting MSBuild to do what I wanted it to, I instead split the solution configuration in two, with one stage for the databases and one for the WinForms project without the databases.
I then used two separate VS Build stages on DevOps with only the WinForms stage still having /target:Publish set.
I've written that up here, but would still like to know the answer to whether it's possible to tell MSBuild not to build the SSDTs when the target is set to Publish?

TFS Build 2013 avoid code analysis

How can I avoid code analysis running on TFS Builds at a solution level?
I understand I can do this at a project level, but there are over 200 projects in my C# solution and I'd like to switch off Code Analysis at solution level if its possible.
I still need to run code analysis on developers machines.
I want to save time by not running code analysis on a specific TFS Build (we use SonarQube for CodeAnalysis on a separate build pipeline and so we don't need TFS Build to do it's own Code Analysis)
I have tried the following in my MSBuild arguments :
/p:RunCodeAnalysis=false
/p:RunCodeAnalysis=Never
(This is using the default TfcvTemplate.12.xaml)
But even with these changes I can still see from the build logs that Code Analysis is still occuring:
csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:TRACE /highentropyva+
/debug:pdbonly /optimize+ /out:obj\Release\xyx.dll
/ruleset:"..\Rule Sets\MinimumRecommendedRules.ruleset"
/subsystemversion:6.00 /target:library /utf8output
xyz.cs
The full MSBuild arguments I use are:
/m /tv:14.0 /p:RunCodeAnalysis=false /p:GenerateProjectSpecificOutputFolder=True
I'm using Tools Version 14 coupled with Microsoft.Compilers NuGet package to allow C#6 on our TFS 2013 Build Server.
Is there a way to avoid running code analysis at solution level, using just the MSBuild args in a TFS2013 build definition?
The RunCodeAnalysis property is used by the old style FxCop static binary analyzers. The new Roslyn Analyzers do not follow this setting.
There are two options...
You can create a Directory.Build.targets1 file in the root folder of your solution (you can create it during build if needed) and remove the analyzers just before the compiler is invoked:
<Target Name="DisableAnalyzersForBuild"
BeforeTargets="CoreCompile"
Condition="'$(TF_BUILD)'=='True'">
<ItemGroup>
<Analyzer Remove="#(Analyzer)"/>
</ItemGroup>
</Target>
You can include the TF_BUILD check to detect that you're inside a Team Build run.
You can also create a ruleset file that disables all rules and override that as part of the build:
/p:CodeAnalysisRuleSet=AllDisabled.ruleset
1) Not sure if this works with the Nuget compiler extensions.

Teamcity 9x ignoring MsBuild parameters

I am trying to build, package and deploy a web application using Teamcity but for some reason Teamcity is ignoring the properties that I am passing to MsBuild.exe.
I have created a step in the build configuration to build, package and deploy teh application to the local server. Here are the properties:
/P:Configuration=Release
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:DeployIISAppPath=MyDeployedWebsitePath
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True
/P:UserName=Administrator
/P:Password=******
/P:MsDeployServiceUrl=MyServerName
Passing them as command line parameters to MSBuild step or declaring them as System Properties in Parameters tabs doesn't seem to work. Teamcity builds the application but ignores the package and deployment steps!
If I execute MSBuild through command line on the same server (with the same params) the package and deployment works.
I am following the steps mentioned in Troy Hunt's series: https://www.troyhunt.com/you-deploying-it-wrong-teamcity_26/
I have read a lot of stack overflow questions and it seems to work seamlessly for others. I am not sure what's going wrong.
I would really appreciate any help.
Update - Build log
> Step 2/2: Build (MSBuild) (51s)
[18:32:48][Step 2/2] ##teamcity[buildStatisticValue key='buildStageDuration:buildStepRUNNER_18' value='0.0']
[18:32:48][Step 2/2] Starting: C:\TeamCity\buildAgent\plugins\dotnetPlugin\bin\JetBrains.BuildServer.MsBuildBootstrap.exe /workdir:C:\TeamCity\buildAgent\work\b12fe165603f4f19 /msbuildPath:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
[18:32:48][Step 2/2] in directory: C:\TeamCity\buildAgent\work\b12fe165603f4f19
[18:32:56][Step 2/2] Targets were not defined in the build configuration.
[18:32:56][Step 2/2] MSBuild command line parameters contain "/property:" or "/p:". It is recommended to define System Property on Build Parameters instead.
[18:33:02][Step 2/2] EnsembleID.Web\EnsembleID.Web.csproj.teamcity: Build target: Build (37s)
[18:33:40][Step 2/2] Process exited with code 0
It turned out to be a version issue :/
I tried different options for MSBuild version - Microsoft .Net Framework 4.5, 4.0 etc.
Finally, Microsoft Build Tools 2015 option worked.
For the past week I have been banging my head on this and I lost track of what all different permutations I tried. I had installed all the different versions of framework tools and web deployment tools, I am not sure why the other options didn't work for me. So if someone is facing a similar problem, make sure to try out different MSBuild version.

Custom MSBuild task in DBProj

I've created a custom MSBuild task for our database project. This tasks uses XLSX file to generate reference data insert scripts that get merged into the post deployment script.
I tested this with a test MSBuild proj and it works well.
Now when I integrate it into the real DBProj file, the output of the task is duplicated and I cant see the MSBuild output logging.
So, my questions are:
1) How can I see the full MSBuild logs in Visual Studio?
2) I'm not sure AfterBuild or BeforeBuild is running twice but maybe?
Thanks
You can debug your MSBuild scripts, set breakpoints, inspect values, etc... See here: http://blogs.msdn.com/b/visualstudio/archive/2010/07/06/debugging-msbuild-script-with-visual-studio.aspx

Can you turn off conditional compilation symbols from msbuild.exe command line?

We have CODE_ANALYSIS defined in our C# components so that FxCop analyzes them when we build them on our development boxes. I would like to have FxCop turned off when it runs through our build system. The build system is obviously using the msbuild.exe command line command. Is there a way to modify the conditional compilation symbols from this executable? If not, does anyone know any other possible solutions to my problem (other than turning it off manually)?
Thanks.
The CODE_ANALYSIS compilation symbol controls whether the SuppressMessageAttribute instances included in the code are copied into the compiled assembly. It does not control whether FxCop runs. If you want to override a project-level MSBuild property like RunCodeAnalysis (which is the beastie that controls whether FxCop runs under MSBuild), you should be able to use the MSBuild.exe /property command line switch. e.g.:
msbuild.exe <...> /property:RunCodeAnalysis=true
Why do you need to turn them off? The best way to set up the project is to define CODE_ANALYSIS for debug configurations only. The release version will not have this value set. That way, when you build production installs, they will not have any references to FxCop.