靜態程式碼分析工具 StyleCop 的兄弟 FxCop,從另外一個面向來分析程式碼。
有關於 FxCop 的相關說明可以參考保哥的這篇文章:介紹好用工具:FxCop ( 靜態程式碼分析 )。
安裝 FxCop Runner Plugin
到「管理 Jenkins」->「管理外掛程式」->「可用的」,搜尋 FxCop,打勾按「直接安裝」即可。
安裝 Microsoft Windows SDK for Windows 7 and .NET Framework 4
FxCop 的安裝檔是包含在 Microsoft Windows SDK for Windows 7 and .NET Framework 4 這個套件裡頭,所以到 Microsoft 的下載中心把 Microsoft Windows SDK for Windows 7 and .NET Framework 4 下載回來,並安裝在 Jenkins Server 上。
安裝 FxCop
瀏覽到 C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\FXCop
裡面有 FxCopSetup.exe,執行它。
設定 FxCop Runner Plugin
將 FxCopCmd.exe 的絕對路徑填入到 Path to FxCopCmd.exe 這個欄位裡面,沒意外的話 FxCopCmd.exe 會在 C:\Program Files (x86)\Microsoft Visual Studio XX.0\Team Tools\Static Analysis Tools\FxCop
裡面。
添加建置步驟 - FxCop exec.
由於 FxCop 不是直接去分析程式碼原始檔,而且從 dll 去分析編譯出來的結果,所以在這邊需要指定要分析的 dll 檔的相對路徑給 FxCop,在 Assembly Files 欄位裡面填 dll 檔的相對路徑。
RuleSet File 欄位可以讓我們指定自訂的 ruleset 檔案,以下是我使用的 RuleSet File 的內容。
<RuleSet Name="SOLID Rules" Description="Mix Microsoft Managed Recommended and Yahoo Code Analysis Rules" ToolsVersion="12.0">
<Localization ResourceAssembly="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.dll" ResourceBaseName="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.Localized">
<Name Resource="SOLIDRules_Name" />
<Description Resource="SOLIDRules_Description" />
</Localization>
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1001" Action="Warning" />
<!--<Rule Id="CA1002" Action="Warning" />-->
<Rule Id="CA1009" Action="Warning" />
<Rule Id="CA1016" Action="Warning" />
<!--<Rule Id="CA1020" Action="Warning" />-->
<Rule Id="CA1031" Action="Warning" />
<Rule Id="CA1033" Action="Warning" />
<Rule Id="CA1049" Action="Warning" />
<Rule Id="CA1060" Action="Warning" />
<Rule Id="CA1061" Action="Warning" />
<Rule Id="CA1063" Action="Warning" />
<Rule Id="CA1065" Action="Warning" />
<Rule Id="CA1300" Action="Warning" />
<Rule Id="CA1301" Action="Warning" />
<Rule Id="CA1302" Action="Warning" />
<!--<Rule Id="CA1303" Action="Warning" />-->
<!--<Rule Id="CA1304" Action="Warning" />-->
<!--<Rule Id="CA1305" Action="Warning" />-->
<Rule Id="CA1306" Action="Warning" />
<!--<Rule Id="CA1307" Action="Warning" />-->
<Rule Id="CA1308" Action="Warning" />
<Rule Id="CA1309" Action="Warning" />
<Rule Id="CA1400" Action="Warning" />
<Rule Id="CA1401" Action="Warning" />
<Rule Id="CA1402" Action="Warning" />
<Rule Id="CA1403" Action="Warning" />
<Rule Id="CA1404" Action="Warning" />
<Rule Id="CA1405" Action="Warning" />
<Rule Id="CA1406" Action="Warning" />
<Rule Id="CA1407" Action="Warning" />
<Rule Id="CA1408" Action="Warning" />
<Rule Id="CA1409" Action="Warning" />
<Rule Id="CA1410" Action="Warning" />
<Rule Id="CA1411" Action="Warning" />
<Rule Id="CA1412" Action="Warning" />
<Rule Id="CA1413" Action="Warning" />
<Rule Id="CA1414" Action="Warning" />
<Rule Id="CA1415" Action="Warning" />
<Rule Id="CA1600" Action="Warning" />
<Rule Id="CA1601" Action="Warning" />
<Rule Id="CA1700" Action="Warning" />
<Rule Id="CA1701" Action="Warning" />
<Rule Id="CA1702" Action="Warning" />
<Rule Id="CA1703" Action="Warning" />
<Rule Id="CA1704" Action="Warning" />
<Rule Id="CA1707" Action="Warning" />
<Rule Id="CA1708" Action="Warning" />
<!--<Rule Id="CA1709" Action="Warning" />-->
<Rule Id="CA1710" Action="Warning" />
<Rule Id="CA1711" Action="Warning" />
<Rule Id="CA1712" Action="Warning" />
<Rule Id="CA1713" Action="Warning" />
<Rule Id="CA1714" Action="Warning" />
<Rule Id="CA1715" Action="Warning" />
<Rule Id="CA1716" Action="Warning" />
<Rule Id="CA1717" Action="Warning" />
<Rule Id="CA1719" Action="Warning" />
<Rule Id="CA1720" Action="Warning" />
<!--<Rule Id="CA1721" Action="Warning" />-->
<Rule Id="CA1722" Action="Warning" />
<Rule Id="CA1724" Action="Warning" />
<Rule Id="CA1725" Action="Warning" />
<!--<Rule Id="CA1726" Action="Warning" />-->
<Rule Id="CA1821" Action="Warning" />
<Rule Id="CA1822" Action="Warning" />
<Rule Id="CA1824" Action="Warning" />
<Rule Id="CA1900" Action="Warning" />
<Rule Id="CA1901" Action="Warning" />
<Rule Id="CA1903" Action="Warning" />
<Rule Id="CA2000" Action="Warning" />
<Rule Id="CA2002" Action="Warning" />
<Rule Id="CA2100" Action="Warning" />
<Rule Id="CA2101" Action="Warning" />
<Rule Id="CA2108" Action="Warning" />
<Rule Id="CA2111" Action="Warning" />
<Rule Id="CA2112" Action="Warning" />
<Rule Id="CA2114" Action="Warning" />
<Rule Id="CA2116" Action="Warning" />
<Rule Id="CA2117" Action="Warning" />
<Rule Id="CA2122" Action="Warning" />
<Rule Id="CA2123" Action="Warning" />
<Rule Id="CA2124" Action="Warning" />
<Rule Id="CA2126" Action="Warning" />
<Rule Id="CA2131" Action="Warning" />
<Rule Id="CA2132" Action="Warning" />
<Rule Id="CA2133" Action="Warning" />
<Rule Id="CA2134" Action="Warning" />
<Rule Id="CA2137" Action="Warning" />
<Rule Id="CA2138" Action="Warning" />
<Rule Id="CA2140" Action="Warning" />
<Rule Id="CA2141" Action="Warning" />
<Rule Id="CA2146" Action="Warning" />
<Rule Id="CA2147" Action="Warning" />
<Rule Id="CA2149" Action="Warning" />
<Rule Id="CA2200" Action="Warning" />
<Rule Id="CA2202" Action="Warning" />
<Rule Id="CA2204" Action="Warning" />
<Rule Id="CA2207" Action="Warning" />
<Rule Id="CA2212" Action="Warning" />
<Rule Id="CA2213" Action="Warning" />
<Rule Id="CA2214" Action="Warning" />
<Rule Id="CA2216" Action="Warning" />
<Rule Id="CA2220" Action="Warning" />
<Rule Id="CA2229" Action="Warning" />
<Rule Id="CA2231" Action="Warning" />
<Rule Id="CA2232" Action="Warning" />
<Rule Id="CA2235" Action="Warning" />
<Rule Id="CA2236" Action="Warning" />
<Rule Id="CA2237" Action="Warning" />
<Rule Id="CA2238" Action="Warning" />
<Rule Id="CA2240" Action="Warning" />
<Rule Id="CA2241" Action="Warning" />
<Rule Id="CA2242" Action="Warning" />
</Rules>
</RuleSet>
Command Line Arguments 欄位填入 /gac
,原因是在執行後出現了下面的錯誤,所以依照官網的指示加上去。
添加建置後動作 - Report Violations
把輸出後的 FxCopReport.xml 填入 fxcop 欄位。
Demo
只要有違反風格的部分,Violations Plugin 都會幫忙整理出來。
後記
實驗的過程當中遇到一個問題,目前我使用的 FxCop 版本無法分析帶有 async 保留字的 method,因此如果 exe 或 dll 內有 async 保留字的 method,FxCop 就會報錯。