3
votes

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:

  1. Copy C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\ to the build server
  2. 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.

2

2 Answers

3
votes

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.

enter image description here

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.

2
votes

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.