Search code examples
.netmsbuildcontinuous-integrationfxcopbuild-server

Running Code Analysis (FxCop > 10) on build agent without installing Visual Studio


After FxCop 10 Microsoft stopped shipping a separate installer for FxCop. Officially one can currently only run code analysis (FxCop 12.0 / 14.0 / 15.0) after installing Visual Studio 2013 / 2015 / 2017. However, we are adamant about not installing Visual Studio on the build agents (the installation needs then to be kept in-sync with what we have got on the developer computers etc.).

So how would i go about getting FxCop 12.0 / 14.0 / 15.0 to work on a build agent, preferrably without installing anything else? I would accept adding a few binaries and msbuild files to source control, though. Otherwise: Is there a way to only install the FxCop stuff using Visual Studio 2013 / 2015 / 2017 installer?

Note: we are using Teamcity as build server.

Answers

As there are multiple valid answers for specific environments and FxCop versions, I've taken the liberty of linking them here for easier access:


Solution

  • Run FxCop 15.0 without installing Visual Studio 2017

    Prerequisites:

    • MSBuild 15.0 --> Install Microsoft Build Tools 2017, you might also want to see here
    • Visual C++ Redistributable for Visual Studio 2017 x86 or here OR Visual Studio 2017 with C++. ---- Note: the x86 version is always required, depending on the build x64 redist may be required as well. If it is missing the error message can be cryptic, for example System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.CodeAnalysis.Interop.dll' or one of its dependencies. The specified module could not be found.). Instead of installing the entire redist you could also copy the necessary DLLs separately, but at this point i don't know which are needed. It's quite tricky and time consuming to find out which ones are exactly missing.

    Depending on what you want to build:

    • appropriate Windows SDK, for example Windows 10 SDK
    • appropriate .net SDK / targets (.NET Framework 4.6 SDK is included in Windows 10 SDK)

    Files to Add to Source Control

    These are the files that i had to add to source control: (Please consider that this might violate some license agreements)

    (source control)\tools\FxCop15
    │
    ├[Engines]
    │   │
    │   ├IntrospectionAnalysisEngine.dll
    │   └PhoenixAnalysisEngine.dll
    ├[Msbuild]
    │   │
    │   ├fxcoptask.dll
    │   ├Microsoft.CodeAnalysis.Targets
    │   ├Microsoft.VisualStudio.CodeAnalysis.dll
    │   └Microsoft.VisualStudio.CodeAnalysis.Sdk.dll
    ├[Repository]
    │   │
    │   ├[Compatibility]
    │   │   │
    │   │   ├Desktop2.0.xml
    │   │   ├Desktop2.0SP1.xml
    │   │   ├Desktop2.0SP2.xml
    │   │   ├Desktop3.0.xml
    │   │   ├Desktop3.0SP1.xml
    │   │   ├Desktop3.0SP2.xml
    │   │   ├Desktop3.5.xml
    │   │   └Desktop3.5SP1.xml
    │   └system32.bin
    ├[Rules]
    │   │
    │   ├DataflowRules.dll
    │   ├DesignRules.dll
    │   ├GlobalizationRules.dll
    │   ├InteroperabilityRules.dll
    │   ├MaintainabilityRules.dll
    │   ├MobilityRules.dll
    │   ├NamingRules.dll
    │   ├PerformanceRules.dll
    │   ├PortabilityRules.dll
    │   ├ReliabilityRules.dll
    │   ├SecurityRules.dll
    │   ├SecurityTransparencyRules.dll
    │   └UsageRules.dll
    ├[x64]
    │   │
    │   └msdia140.dll (1349 KB)
    ├[Xml]
    │   │
    │   ├CodeAnalysisReport.xsl
    │   ├FxCopReport.xsl
    │   └VSConsoleOutput.xsl
    ├Architecture-msil.dll
    ├CodeAnalysis.dll
    ├CustomDictionary.xml
    ├FxCopCmd.exe
    ├FxCopCmd.exe.config
    ├FxCopCommon.dll
    ├FxCopSdk.dll
    ├Microsoft.Cci.dll
    ├Microsoft.VisualStudio.CodeAnalysis.Common.dll
    ├Microsoft.VisualStudio.CodeAnalysis.DataflowModels.dll
    ├Microsoft.VisualStudio.CodeAnalysis.dll
    ├Microsoft.VisualStudio.CodeAnalysis.Interop.dll
    ├Microsoft.VisualStudio.CodeAnalysis.Phoenix.dll
    ├Microsoft.VisualStudio.CodeAnalysis.Phoenix.xml
    ├msdia140.dll (1057 KB)
    ├mssp7en.dll
    ├mssp7en.lex
    ├phx.dll
    └Runtime-vccrt-win-msil.dll
    

    Copy them as follows:

    • entire FxCop installation folder contents from

      %programfiles(x86)%\Microsoft Visual Studio\2017\ **INSERT EDITION HERE** \Team Tools\Static Analysis Tools\FxCop

    • from Visual Studio 2017 C++ redist (or your Visual Studio 2017 Installation, if you've got VC++ workload installed: %ProgramFiles(x86)%\Microsoft Visual Studio\2017\\VC\Redist\MSVC\14.12.25810) or any other place: (also see legal information) copy msdia140 x86 and x64 (mine have the version 14.12.25810.0) to:

      msdia140.dll (1.12 MiB)

      amd64\msdia140.dll (1.42 MiB)

    • All files from %programfiles(x86)%\\Microsoft Visual Studio\2017\ **INSERT EDITION HERE** \MSBuild\Microsoft\VisualStudio\v15.0\CodeAnalysis to

      Msbuild\fxcoptask.dll

      Msbuild\Microsoft.CodeAnalysis.Targets

      Msbuild\Microsoft.VisualStudio.CodeAnalysis.dll

      Msbuild\Microsoft.VisualStudio.CodeAnalysis.Sdk.dll

    Additionally i adjusted the project msbuild file (*.csproj) as follows:

    <!-- Microsoft.CSharp.targets import is contained in csproj by default. This just goes to show the sequence -->
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
    
    <!-- now this must be added -->
    <Import Project="$(ProjectBuildScriptDir)Custom.CodeAnalysis.targets"/>
    

    And this is what our Custom.CodeAnalysis.targets contains:

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
        <!-- Code analysis settings. -->
        <PropertyGroup>
            <!-- this must reference the path where you copied the FxCop stuff to -->
            <FxCopDir>..\FxCop15\</FxCopDir> 
            <CodeAnalysisCulture>en-US</CodeAnalysisCulture>
            <CodeAnalysisRuleSet>$(SolutionDir)FxCop.ruleset</CodeAnalysisRuleSet>
            <!-- you can and should use another condition here. Otherwise code analysis will be run on every build in VS as well. -->
            <!-- in my build setup i do something like Condition=IsRunningOnTeamCity => true -->
            <RunCodeAnalysis>true</RunCodeAnalysis> 
            <CodeAnalysisTreatWarningsAsErrors Condition="'$(IsRunningOnTeamCity)' != 'true'">true</CodeAnalysisTreatWarningsAsErrors>
        </PropertyGroup>
    
        <Import Project="$(FxCopDir)Msbuild\Microsoft.CodeAnalysis.Targets" />
    
        <Target Name="CodeAnalysisLogHeader" BeforeTargets="RunCodeAnalysis" Condition="$(RunCodeAnalysis) == 'true' OR $(RunCodeAnalysisOnce) == 'true'">
            <Message Text="Text, Executing Code Analysis (FxCop) on $(MsBuildProjectName)" Importance="High" />
        </Target>
    
    </Project>
    

    Notes for Visual Studio Paths:

    The path to the visual studio installation is edition dependent. It includes Professional and Enterprise. AFAIR the community edition has a different path, but also does not support FxCop. Corrections welcome :-)