.NET Projects: Analyzing Code with FxCop
Introduction
In previous articles, I have described setting up a project repository in Subversion, structuring a repository, and automating project builds with NAnt. Thanks in particular to NAnt, the following tasks can be automated as part of a project build process:
- compile code - done
- run unit tests
- perform code analysis
- generate documentation
- create distributable packages
In this article, I will be continuing in this vein by introducing some code analysis into the mix…I know I’m skipping over the unit tests item, but that is a topic for another day, and this should be an easier one to get done right now.
So, without further ado, it’s time to start checking project code for best practices using FxCop.
What is FxCop?
FxCop is a freeware tool provided by Microsoft. It is used to analyze compiled assemblies (e.g. .dll and .exe files) and report on the use (or lack thereof, in this case) of best practices in code. This is based on Microsoft’s design guidelines, and FxCop can be configured on a project-by-project basis for what rules should be checked. There even exists the capability to add custom rules.
Through all this, FxCop helps you write better, clearer code. But it doesn’t account for overall project architecture, oh no that’s something else. It is also not a replacement for code reviews - you still need humans for that! But in the end it is still a very useful supplemental tool.
The software is built on .NET 2.0, so you will need the appropriate .NET runtime installed, although if you are reading this, chances are you have that already. Despite being built in .NET 2.0, the tool can be run against all versions of the framework, which is a good thing!
How to use FxCop
Go ahead and download the FxCop package (version 1.35 as of this writing) from the link above (it isn’t very large). Run the installer. Note that the app is just some compiled exes and dlls, so it can easily be added to a system without needing an actual installation routine…The joy of .NET assemblies! Open up the FxCop executable. The opening screen should resemble the following image:
This is a blank slate as far as FxCop is concerned, so go ahead and add some compiled assemblies to analyze. This is done by clicking the Add Target for Analysis button (
) in the toolbar. Navigate to and select the targets to be analyzed. The targets can be any .dll and .exe files, as long as they are produced by .NET. Heck, you can check on other software written in .NET this way!
The above image shows my FxCop project with 3 assemblies of my Wadmt project added. You may well have more or fewer items than I do in this case.
After adding targets to the project, you can save the FxCop project information to a file. Click the Save Project button (
) and specify a name and location for the project file. The file is saved with a .fxcop extension. When FxCop is installed, it automatically registers that extension for itself. Double-clicking the file will open it in FxCop.
Even though it has the .fxcop extension, the file is in an XML format (a good thing), and is rather large too. When I opened mine in a text editor, there were over 7,000 lines in it! But the information within seems quite detailed. It indicates the targets of the project, the rules to be validated, and any custom rules and settings as well.
Now that a basic project has been defined, return to FxCop and hit the Analyze button (
) to run the analysis. Depending on the size of the code base being analyzed, the process might take a minute or two. Time to see the results…
Examining Results
The image above shows a sample of the output from running FxCop on my own project. I had 835 messages at the time…hmm, looks I’ve got some work ahead of me to clean up my act. Depending on your coding practices and your project size, your result set will undoubtedly vary.
A brief overview of the returned messaged is displayed in the right pane of the FxCop window. Clicking on one of them shows more information in the Properties box at the bottom of the window, as shown in the following image:
The detail, among other things, indicates the source of the message, provides a link where you can read more about the nature of the rule involved, and gives more detail about the particular message. It will usually suggest a way to resolve the message; it is up to you whether to follow the suggestion, or to do your own customization of the rules (see Customizing Rules, below) to override the defaults.
If you choose to follow the design guidelines, you will need to make the appropriate edits to your source and rebuild the project. At which point you can re-run the FxCop analysis and see where your project is now. Of course, it may be more efficient to make a number of related changes at a time, then rebuild and re-analyze. Repeat as necessary.
Customizing Rules
As shown in the image, FxCop checks your code for conformance in the following areas, with over 200 rules:
- design
- globalization
- interoperability
- mobility
- naming
- performance
- portability
- security
- usage
The rules are all selected by default, but can be deselected and reselected as necessary. Note that each of the initial items are just groupings of multiple rules within a common category. Clicking the + beside the group will show the actual rules within the group (see image below).
Some of the groups are small or medium-sized, and others are rather large. The rules within each group can be individually selected and deselected. Selecting or deselecting a group does the same to all rules within. This way, depending on your requirements, you can cherry-pick which rules should and should not be used on your project. The selection information is saved into your FxCop project file.
It should be noted that it is probably a good idea to use all the rules initially, so you can get a broad idea of how much work may be involved in resolving the resulting messages. It is also worth noting that the full set of rules is not for everyone, and, based on personal/departmental/organizational standards, can be tweaked to suit such standards. So if your department or company uses a coding standard not recognized by FxCop, you can make FxCop aware of your standards. This can be done by deselecting individual rules that conflict with your own standards, and also by using custom rules.
If there are certain rules that you do not wish to be validated against your project, you can uncheck such rules in the rules list within FxCop. Then try rerunning the analysis within FxCop and see how your results vary. Another interesting thing to do is to check just one group at a time, and see what messages come up as a result of analysis. This will give you an idea of what category of issues the messages go into. In my case, the majority of messages were divided between the Design and Usage categories, while the remaining messages were spread out in varying amounts among the remaining categories.
Similarly, you can check and uncheck the boxes next to your targets, thereby including or excluding them from the analysis. You can also expand the targets to view lists of types defined within the targets, and much like individual rules, individual types can be included in or excluded from analysis.
FxCop custom rules is another interesting topic, but is definitely beyond the scope of this introduction, so I will say no more on that subject right now. But the built-in rules give you plenty of flexibility and customization as it is.
Using Custom Dictionaries
When FxCop analyzes assemblies, among all the other analyses, it seems to do a basic spell check. This is generally a good thing, as typos in code can be annoying; and more to the point, it can catch other spelling mistakes, such as in strings and the like. However, there may be situations where this works against you, like when FxCop points out a word that it thinks is misspelled, but in fact is not. This could be in the case of a project name, or a class name, or variable or namespace names. The names for these may well be valid in the human mindset, and FxCop takes spell check a little too literally in these cases.
This also applies to the case of code keywords (being able to mark certain keywords as deprecated, and suggest alternates) and acronyms and abbreviations that may be used in code. These in particular are not always standard dictionary words, so it helps to make FxCop aware of these.
To that end, FxCop has a feature where you can specify words that should and should not be recognized as proper words. This feature is called Custom Dictionary, and it is a useful technique. Custom dictionaries are not managed from within FxCop itself. Rather, they reside in files called CustomDictionary.xml, alongside an FxCop project file. When a particular FxCop project is run for analysis, the software automatically picks up on the matching dictionary file, and uses the contents during analysis.
Following is an example custom dictionary that is shown in the FxCop documentation:
<Dictionary>
<Words>
<Unrecognized>
<Word>cb</Word>
</Unrecognized>
<Recognized>
<Word>stylesheet</Word>
<Word>GotDotNet</Word>
</Recognized>
<Deprecated>
<Term PreferredAlternate="EnterpriseServices">ComPlus</Term>
</Deprecated>
</Words>
<Acronyms>
<CasingExceptions>
<Acronym>CJK</Acronym>
<Acronym>Pi</Acronym>
</CasingExceptions>
</Acronyms>
</Dictionary>
The sample is straightforward: it clearly defines words that should be recognized as actual words, and ones that should not be. The sample also shows how potentially confusing (to FxCop) acronyms may be handled.
Based on the general sample, I have started a (very) basic custom dictionary of my own, and saved it in the same directory as my project’s .fxcop file.
In my case, FxCop was tossing messages on the validity of the Wadmt keyword. Wadmt is the name of my project, and so is a valid word, and is found throughout my project in namespace definitions and imports. I eliminated a number of recurring messages based on this word by introducing my custom dictionary, shown below.
<Dictionary>
<Words>
<Recognized>
<Word>Wadmt</Word>
</Recognized>
</Words>
</Dictionary>
It is pretty basic right now, but as shown by the sample dictionary further up, there is certainly room for future additions.
And that’s…
…FxCop in a nutshell. Now, this software will be useful for ensuring code is of decent quality, but on its own it still needs to be run manually after a build. However, since the .NET project is already using NAnt to automate the process, and FxCop has a command-line interface, a task can be added to the build script to run FxCop automatically.
Adding FxCop Task to NAnt Script
With a basic build script already in place, adding an FxCop code analysis task is a quick process. In my case, all I needed to do was add the following task to my wadmt.build file:
...
<!-- specify location of required tools -->
<property name="dir.tools" value="tools\" />
...
<!-- analyze build for code quality -->
<target name="analyze.fxcop" depends="build" description="Analyze generated code using FxCop">
<!-- specify location of input and output files -->
<property name="fxcop.input" value="wadmt.fxcop" />
<property name="fxcop.output" value="${dir.build}fxcop-results.xml" />
<!–- send the analysis work to the FxCop command-line tool -–>
<exec program="${dir.tools}fxcop\FxCopCmd.exe" failonerror="false">
<arg value="/project:${fxcop.input}" /> <!–- use the fxcop project file -–>
<arg value="/forceoutput" /> <!–- create output even if no violations are found -–>
<arg value="/summary" /> <!–- show some summary info -–>
<arg value="/out:${fxcop.output}" /> <!–- specify an output file -–>
</exec>
</target>
…
The key point is the line starting with <exec, as that is what actually runs the FxCop command-line tool, FxCopCmd.exe. In a general sense, NAnt’s exec item allows you to run any command-line software. As shown above, you can pass parameters to the software being run by use of <arg /> tags, within the <exec> element. The parameter values will be based on what the command-line tool is expecting.
Here I will point out that there is a slightly more direct way to do this…NAnt itself does not have a dedicated fxcop task, but the NAntContrib project does. NAntContrib is a separate, free download of additional tasks that have not yet been integrated into the NAnt core. Including a task dedicated to running FxCop analyses. To use this feature, you would need to download the latest NAntContrib package, unzip, and copy the contents of the bin folder over to the NAnt bin folder. This is NAnt knows where the additional functionality is found. Then the FxCop analysis task could be rewritten as:
...
<!-- specify location of required tools -->
<property name="dir.tools" value="tools\" />
...
<!-- analyze build for code quality -->
<target name="analyze.fxcop" depends="build" description="Analyze generated code using FxCop">
<!-- specify location of input and output files -->
<property name="fxcop.input" value="wadmt.fxcop" />
<property name="fxcop.output" value="${dir.build}fxcop-results.xml" /> <!–- send the analysis work to the FxCop command-line tool -–>
<fxcop projectFile="${fxcop.input}" analysisReportFilename="${fxcop.output}" failonerror="false"></fxcop>
</target>
…
This method is available if desired…Myself, I won’t bother, as the <exec /> technique works well enough, using NAntContrib means another dependency, and the project seems to be at a standstill. Looking at the website, the last news of any kind was well over a year ago. However, the option is there for those that want it.
I decided to include FxCop in my project repository, for mostly the same reasons as I did with NAnt: it’s not very large, versions will be consistent for all working copies, one less package to install separately, and it’s easier to use when I know it’s a short distance away from my actual project. I also included the FxCop project file at the root of the trunk, alongside the build file, and the CustomDictionary.xml to go along with it.
The default target for my build script is the build target, and I want to keep it that way as I may not necessarily want to do the code analysis every time I compile my project. But by using the build.bat file shown in the previous article, I can type the following in a command prompt at the root directory of my working copy:
build fxcop
That line runs the FxCop task within the build script, after doing the actual build first, since FxCop needs assemblies in place to be able to analyze them (hence the depends attribute on the task element). So by executing the above line, I ensure that there will always be a build in place for FxCop to do its work on.
After all that, the following image shows the output from the fxcop task:
And an XML file is created in my build directory, containing the results of the analysis. It can be viewed with a web browser, but is not as rich as doing the analysis from within the FxCop application. However, the results file is there, ready to be perused. And if you preferred, you could use the FxCop application to examine results after a build is done.
I will point out that FxCop can be used as an external tool from within Visual Studio as well, if that is desirable for you.
Conclusion
So after the intro to FxCop, and adding a new task to the NAnt build script, we have an automated project build AND code analysis process. NAnt handles the overall build process, and delegates certain specialized tasks as necessary. The subject of this article was checking code for best practices by using Microsoft FxCop.
By including the FxCop software in my project’s tools folder, I reduce the external dependency, as I can do a single checkout on any computer and instantly have all the tools I need to build the project. The same goes for my FxCop project file, which I put at the root of the project directory, alongside the wadmt.build file.
I’ll repeat the list of components of a build process here as a review.
- compile code - basics are done, can be extended as necessary
- run unit tests
- perform code analysis - added code analysis using FxCop
- generate documentation
- create distributable packages
I’m not sure yet which the next item will be, although the unit tests one is likely. There are some articles-in-progress already though, so whichever gets done first, gets published next. I will also point out that there will be at least one more article on the code analysis subject, as there are different ways to analyze code, and some of these are also of interest in addition to FxCop.
Extra Reading
- Another FxCop overview - also covers commonly-used rules
- MSDN FxCop forum - ongoing discussions
- MSDN Magazine article - talks a bit about custom rules
Kevin
I’ve actually used this program before and it does have some usefulness. But what I didn’t like about it was that some of the rules that are on by default can be rather annoying, like ones that say how you should name your variables, like on the casing you use and such. But more to the point, why is such an error a breaking issue? It doesn’t affect the code execution.
But of course you can turn those off as you mentioned.
My other problem with is that some people that I’ve ran into blindly follow whatever it says with the default config. And if you problem has any issues, its crap code. Which isn’t true of course.
January 23, 2008 at 7:42 PM |
Grant
Fair point. I would respond that the rules are very configurable, so they can be tailored on a project-by-project basis, or be based on personal or departmental coding standards.
True, even if actual code doesn’t follow the rules, it works all the same. But I see FxCop as a way to ensure that coding standards are consistent throughout a project, which I think is the main point.
It seems to me that the default rules are there merely as a starting point, and they can be customized to suit.
January 23, 2008 at 7:42 PM |
.NET Projects: Unit Testing with NUnit | GrantPalin.com
[...] and structure a Subversion repository, use NAnt to automate the project build process, and use both FxCop and NDepend to analyze the [...]
June 8, 2008 at 7:42 PM |