Creating Custom FXCop rules and altering existing ones - Part 2
In my previous post, I talked about creating custom FXCop rules for the latest (1.32) versaion of FXCop and a template/example project library that I have made available to ease that process.
What I also needed to do was to alter some of the Microsoft supplied rules. In one specific instance, I wanted to completely disable, or remove the 'CompoundWordsShouldBeCasedCorrectly' rule that is contained within the 'NamingRules.dll' assembly that comes shipped with FXCop 1.32. This rule complains about things like the word 'WebPart', and that it should be 'Webpart' instead. Personally, I dont like the rule, and it just adds confusion and clutter to the analysis report. Sure you can exclude this *after* an analysis run has completed, but I wanted to be able to ship a set of rule assemblies, and simply have the rules applied that I wanted *without* the user having to exclude specific rules.
To do this, I did the following:
- Loaded the 'NamingRules.dll' into ILDasm, and produced a 'dump' of the IL code to a text file (*.il file)
- Loaded the file into notepad and removed the offending rule and any references to the rule from the IL code. The IL Code looked something like this :
.class private auto ansi sealed beforefieldinit CompoundWordsShouldBeCasedCorrectly
.field private static initonly char s_parseCharacters
.field private static class [FxCopSdk]Microsoft.FxCop.Sdk.CaseInsensitiveDictionary s_exceptions
.field private static class [FxCopSdk]Microsoft.FxCop.Sdk.CaseInsensitiveDictionary s_shouldBeCompound
...rest of code....
- As you can see, IL code is actually realtively verbose and you dont require a huge understanding of it to simply highlight sections and remove them.
- Next I removed the 'publickey' entry from the IL. Each rule assembly provided with FXCop is strongly named, and altering it then recompiling it without removing the strong name/public key, means it will fail when attempted to be loaded as the CLR detects that it is strongly named, however the public key token is invalid due to the modifications we have made, and a load failure occurs. The IL code for the public key token looks like:
.publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 // .$..............
00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 // .$..RSA1........
B5 FC 90 E7 02 7F 67 87 1E 77 3A 8F DE 89 38 C8 // ......g..w:...8.
1D D4 02 BA 65 B9 20 1D 60 59 3E 96 C4 92 65 1E // ....e. .`Y>...e.
88 9C C1 3F 14 15 EB B5 3F AC 11 31 AE 0B D3 33 // ...?....?..1...3
C5 EE 60 21 67 2D 97 18 EA 31 A8 AE BD 0D A0 07 // ..`!g-...1......
2F 25 D8 7D BA 6F C9 0F FD 59 8E D4 DA 35 E4 4C // /%.}.o...Y...5.L
39 8C 45 43 07 E8 E3 3B 84 26 14 3D AE C9 F5 96 // 9.EC...;.&.=....
83 6F 97 C8 F7 47 50 E5 97 5C 64 E2 18 9F 45 DE // .o...GP..\d...E.
F4 6B 2A 2B 12 47 AD C3 65 2B F5 C3 08 05 5D A9 ) // .k*+.G..e+....].
- Once that is removed, save the file, then run it through the 'ilasm' tool to recompile the IL code into a valid assembly.
- Copy this new assembly into the FXCop rules directory (keep a copy of the old assembly but remove it from the directory) and thats it. The rule we removed will never be executed as its simp not present.
This process sounds a little difficult or complex, however it took me approximately 20 minutes to remove 1 rule. Not a big deal really and now I can ship the rule assemblies I want, and overwrite those currently shipped with FXCop to get exactly the set of rules I intend, and only those rules.