Where to put Rule Sets for MSBuild 15 (Build Tools for Visual Studio 2017) - msbuild

When enabling Static Code Analysis on my builds, I get the following error thrown by MSBuild:
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\Microsoft.CSharp.CurrentVersion.targets(134,9): warning MSB3884: Could not find rule set file "AllRules.ruleset". [C:\Program Files\VSTS Agent_work\PATH_TO_MY.csproj]
To get Static Code Analysis working on build agents (only MSBuild, no Visual Studio), for older versions of the build tools one would:
Copy C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\ to the build server
Add a registry entry pointing to that folder
(see also this bug report)
However, these instructions doesn't work with "Build Tools for Visual Studio 2017". I'd like to know how I resolve this, without needing to copy the rulesets into my own repository or changing anything in my csproj?
Update:
I've tried setting the following registry key, to no avail:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\15.0\Setup\EDev]
"StanDir"="C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\Team Tools\\Static Analysis Tools"
Digging through the registry, I've found that the following registry keys. On my machine I've installed both VS2017 Build Tools and Test Agent, and it seems like this points to the latter, which I have installed after installed Build Tools:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7]
"15.0"="C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\TestAgent\\"
"14.0"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\"
Update 2:
Both answers mention the file Microsoft.CodeAnalysis.Targets. However this file is not present on my build server. I've tried copying this folder over from my VS2017 installation:
from: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\VisualStudio\v15.0\CodeAnalysis
to: C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0\CodeAnalysis
However besides the rulesets not being found, it now also throws errors about being unable to find Microsoft.WebApplication.targets:
XXX.csproj(296,11): error MSB4226: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuil
d\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" was not found. Also, tried to find "WebApplications\Microsoft.WebApplication.targets" in the fallback search path(s) for $(VSToo
lsPath) - "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0" . These search paths are defined in "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe.Config".
Confirm that the path in the declaration is correct, and that the file exists on disk in one of the search paths.

Update:
Based on my test, you don't need to change anything manually, just need to install the default components of Build Tools for VS2017, then the necessary files will be added automatically.
Old:
Regarding default folder of code analysis files, you can check Microsoft.CodeAnalysis.targets file:
<PropertyGroup>
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'=='' and Exists('$(VsInstallRoot)\Team Tools\Static Analysis Tools\')">$(VsInstallRoot)\Team Tools\Static Analysis Tools\</CodeAnalysisStaticAnalysisDirectory>
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the first registry path, assume we're in a 64bit process. -->
<!-- read registry from Wow6432Node -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\VisualStudio\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- if we didn't find the registry path yet, then try Win8 Express location -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Microsoft\VSWinExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the registry path yet, then try Win8 Express 64-bit location -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\VSWinExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the registry path yet, try WP Express locations -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Microsoft\VPDExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the registry path yet, try WP Express 64-bit locations -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\VPDExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the registry path yet, try WD Express locations -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Microsoft\WDExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- If we didn't find the registry path yet, try WD Express 64-bit locations -->
<CodeAnalysisStaticAnalysisDirectory Condition="'$(CodeAnalysisStaticAnalysisDirectory)'==''">$(Registry:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\WDExpress\15.0\Setup\EDev#StanDir)</CodeAnalysisStaticAnalysisDirectory>
<!-- Default rule set search paths -->
<CodeAnalysisRuleSetDirectories Condition=
"'$(CodeAnalysisIgnoreBuiltInRuleSets)'!='true' and
'$(CodeAnalysisStaticAnalysisDirectory)'!=''">$(CodeAnalysisRuleSetDirectories);$(CodeAnalysisStaticAnalysisDirectory)\Rule Sets</CodeAnalysisRuleSetDirectories>
<!--
In scenario where we run CA from command-line , we don't get "CodeAnalysisVSSku" variable passed by the IDE, so in case of Express-only installation
we attempt to load rule sets that are only present on Pro and above - and fail. Let's assume we're in "Express" mode if the Pro+ rule set doesn't exist.
-->
<CodeAnalysisVSSku Condition="'$(CodeAnalysisVSSku)'=='' and !Exists('$(CodeAnalysisStaticAnalysisDirectory)\Rule Sets\NativeRecommendedRules.ruleset')">Express</CodeAnalysisVSSku>
</PropertyGroup>
Based on the code, you just need to put the code analysis rule files in $(VsInstallRoot)\Team Tools\Static Analysis Tools folder and the value of $(VsInstallRoot) is C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools if you just install Build Tools for Visual Studio 2017 on the build server.
To conclude, you just need to put rule files in C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Team Tools\Static Analysis Tools folder.

Officially you'd need to install Visual Studio onto the build server, as the Code Analysis these rules come from are part of Visual Studio, not of MsBuild.
You can still copy the Static Analysis directory to your build server and supply the following parameter to MsBuild in the Additional Arguments option:
/p:CodeAnalysisStaticAnalysisDirectory=c:\analysisdirectory
Or copy just the rule files and specify this MsBuild argument, that's probably easiest when you put the rules files in source control:
/p:CodeAnalysisRuleDirectories=c:\analysisdirectory\rules
Optionally you could edit the project file and set the property in a property group.

Related

MSBuild looking in wrong place for Microsoft.VisualBasic.Core.targets

I am setting up a new TeamCity build agent. Several build configurations that run perfectly well on the existing agent are failing on the new agent, with errors like this (whitespace added for clarity):
[22:14:32][someproject.vbproj]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\bin\Microsoft.VisualBasic.CurrentVersion.targets(322, 5):
error MSB4019: The imported project
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\bin\Roslyn\Microsoft.VisualBasic.Core.targets"
was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
Note the path on line three after "The imported project". The error is correct; the folder does exist but the file does not exist there. However the Microsoft.VisualBasic.Core.targets file does exist at a slightly different path
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\Roslyn\Microsoft.VisualBasic.Core.targets
Is there an easy fix for this, perhaps a registry entry telling MSBuild where to look?
Cause
On your machine, there are two copies of VS 2017 installed, Professional edition and the raw Build Tools.
You didn't install VB bits for Professional, while did that for Build Tools.
TeamCity prefers MSBuild from Professional edition.
Combine all above, the issue happened.
Fix
You should either force TeamCity to use MSBuild from Build Tools, or add VB to your VS Pro installation.
Reference
https://blog.lextudio.com/the-rough-history-of-msbuild-cc72a217fa98

BuildMaster using MSBuild 15.0

How do I target MSBuild 15.0 on my server? I have 15.0 installed on the server but my project is still building with 14.0. I know that Microsoft has made some changes to the directory locations and no longer uses the registry values with 15.0.
I found 15.0 installed in the following locations:
C:\Program Files (x86)\MSBuild\15.0
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild
And I have the .Net framework 4.6.2 installed here:
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
Thanks!
Product: BuildMaster
Version: 5.7.2
Update 1:
Responding to #emiel-koning, I tried to specify $MSBuildToolsPath in the build step using:
set $MSBuildToolsPath = C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin;
But I get this error:
error MSB4226: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" was not found. Also, tried to find "WebApplications\Microsoft.WebApplication.targets" in the fallback search path(s) for $(VSToolsPath) - "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0" . These search paths are defined in "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe.Config". Confirm that the path in the declaration is correct, and that the file exists on disk in one of the search paths.
Update 2:
Could I be missing something installed on my build server? I installed Visual Studio Build Tools which gave me the MSBuild 15.0 but not the WebApplication.targets file from the error above
SOLUTION
I fix my issues by also installing "Web development build tools" component. I also set the $MSBuildToolsPath at the server level until I can roll out the new MSBuild globally.
In general, this is handled by the ToolsVersion attribute of the project file. This should be what is used if the below configuration is not specified.
In BuildMaster specifically, you can override this value per-server on the Administration > BuildMaster Extensions > Windows SDK > Configuration tab. Click on $MSBuildToolsPath (and optionally override at a specific scope) with a value of C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin
Response to Updates #1 & #2:
First, don't set that variable in the plan itself (otherwise you'd have to set it in every plan). Set it in the manner I described above. Personally, I always specify its value at the server level since each server may have it installed in a different location.
As for Microsoft.WebApplication.targets, I think the only supported method of building web application projects is to have Visual Studio installed on the build server; though in the past I've just copied the targets from my local installation (C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications) into the path that MSBuild is expecting them to be.
Can you use $MSBuildToolsPath to specify the correct path to MSBuild?

MS Build task cannot find AL.EXE

The issue is the following:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2863,5):
error MSB3086: Task could not find "AL.exe" using the SdkToolsPath ""
or the registry key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft
SDKs\Windows\v8.0A\WinSDK-NetFx40Tools-x86". Make sure the
SdkToolsPath is set and the tool exists in the correct processor
specific location under the SdkToolsPath and that the Microsoft
Windows SDK is installed
I've tried various laborious solutions found on the web, but finally I managed to solved the issue like this:
Go to C:\Windows\Microsoft.NET\Framework\v4.0.30319\
Open with a text editor the file Microsoft.Common.targets
Search for "al.exe" in the file at step 2 and replace the "ToolPath" and "ToolExe" fields with the actual path of the "al.exe" file.
I have setup the two fields at step 3 in the following way:
ToolPath="C:\Program Files (x86)\Microsoft
SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\"
ToolExe ="C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\al.exe"
Thanks.
You should register variables before MSBuild call:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat
I use psake, it registers vars automatically.
Alternative solution - add a param:
msbuild.exe "/p:TargetFrameworkSDKToolsDirectory=C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools"
You need to check the path of "msbuild.exe"
I solved the same problem by changing the path
from
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
to
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin

XAML Build InvokeProcess build variables

I am currently doing an invoke process from my custom XAML build definition to run VSTest.Console.exe with some parameters. I have hard coded the path to the Visual Studio folder in the FileName property. I would like to use the $(VSINSTALLDIR) variable instead of hard coding the C:\Program Files (x86)\Microsoft Visual Studio 14.0\ portion of the path since I believe that the $(VSINSTALLDIR) points to the latest (or perhaps last?) installed version of Visual Studio.
Below is my current InvokeProcess XAML directive:
<mtbwa:InvokeProcess Arguments="[msTestParamsBuilder.ToString()]" DisplayName="Invoke VSTest.Console for Test Assemblies" FileName="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\VSTest.Console.exe" sap2010:WorkflowViewState.IdRef="InvokeProcess_4" WorkingDirectory="[BuildDirectory]">
$(VSINSTALLDIR) is not the environment variables in TFS. TFS build does not apply the value of $(VSInstallDir) macros (C:\Program Files (x86)\Microsoft Visual Studio 14.0\ ) Detail info about the environment variables in TFS build please refer this link: Team Foundation Build environment variables
In your case, you need to add the value in XAML build config:
Process->Build->5. Advances->MSBuild arguments add /p:VSInstallDir = Value

Error doing an MSBuild on a CLR Storedprocedure project on Build Server

When building a CLR Storedprocedure Project using MSBuild on our build server (Team City) we're getting the following error:
error MSB4019: The imported project
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\SqlServer.targets"
was not found. Confirm that the path
in the declaration is
correct, and that the file exists on
disk
I've checked to see if the file exists on disk and sure enough it doesn't. I've checked on my own machine and it does exist.
I don't really want to start copying over files manually to the build server.
Here's the line from the csproj file which is being imported to the proj file:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildToolsPath)\SqlServer.targets" />
Here's the line from the proj file which is being run by our Team City Server:
<Import Project="..\$(ProjectName).csproj"/>
My question is really:
Where does this file comes from? Is it part of the Visual Studio install for example.. Or is there some re-distribution package somewhere to allow me to compile this project on our build server?
Thanks
BTW.. if i just copy the file onto the Build server it does actually work.
Dave
Looks like it's part of the v2.0 framework install that gets moved into the v3.5 directory after that's added. You can either reinstall v2.0 of the framework or manually copy the file out of the v3.5 folder.
Up to Visual Studio 2012, the SqlServer.targets was deployed on the .NET Framework's msbuild.exe location, like
c:\Windows\Microsoft.NET\Framework\v4.0.30319\
c:\Windows\Microsoft.NET\Framework\v3.5\
c:\Windows\Microsoft.NET\Framework\v2.0\
In modern versions, from Visual Studio 2013 on, the MSBuild tool is included with Visual Studio, and the MSBuild.exe and .targets files are deployed in their own folder. For example fo Visual Studio 2013:
c:\Program Files (x86)\MSBuild\12.0\Bin\
(NOTE: 12.0 is the "internal" version number of VS2013)
IMPORTANT NOTE: SqlServer.targets only exists if you install SQL Server Data Tools in your Visual Studio Deployment.