» Publishers, Monetize your RSS feeds with FeedShow: More infos (Show/Hide Ads)
Hi Everyone,
With the launch of the Beta we would like to tell you about some of the great enhancements we have made to code analysis based on your feedback. Back when we started planning for Visual Studio 2012 we spent a good deal of time talking with people who use code analysis, and understanding the common pain points. What we learned was there are three key areas you would like to see us improve:
- Help better manage large numbers of warnings
- Make the output from the analyzer more understandable
- Improve the accuracy of the analyzer and the types of coding errors it finds
In this post let’s go over some of the highlights for code analysis in Visual Studio 2012:
- Code Analysis is available in all editions of Visual Studio and supports 64bit C++ projects
- Custom rule sets for C++ projects and quick keyword filtering for managing results
- Ability to step through each line on the warning path to improve understanding of the issue
- More accurate, relevant warnings to find important bugs early in development
Code Analysis Available in All Editions of Visual Studio
First, we are really excited to announce that we are including code analysis in all editions of Visual Studio 2012, including a subset of the most critical warnings in the Express edition for free (this applies to C++, C#, and VB code analysis) and all rules in the Professional, Premium, and Ultimate editions. We see code analysis as an important tool for writing high quality software, and we want you to have access to the same tools that we run internally at Microsoft.
Filtering and C++ Rule Sets
Historically, one of the difficult things about using code analysis has been managing the sometimes large sets of results. When we would run analysis on a moderate or large codebase for the first time the sheer number of warnings returned was overwhelming. Finding ways to carve off small bits was difficult.
To help with this we have created a new window for managing Code Analysis results.
This window contains a keyword filter text box where you can filter code analysis results on warning number, text in the title or message of the warning, as well as filename or function name. We have found this is really useful for quickly getting to the code analysis warnings that are most relevant. For example, say you are adding a new function to an existing project that has previous code analysis warnings in it, and you just want to see any new warnings you may have added. Using keyword filtering you can filter on your new function name and investigate those first.
In addition, if you are using Visual Studio 2012 Professional, Premium, or Ultimate editions you can now create custom rule sets for C++ projects. The rule set configuration file determines which warnings Code Analysis checks for. We have included a default rule set that we think is a great place to start, but we encourage you to customize the rule set to make Code Analysis more relevant to you. For instance, if your organization cares about globalization defects because you ship your software in multiple languages you can enable these rules, or vice versa.
Detailed Explanation of Code Path to Warning
Another part of the C++ code analysis experience we set out to improve is around understanding how the analyzer found the problem. Previously when investigating a code analysis warning we would often scratch our heads and say to ourselves “ok, it’s telling me there is a bug on this line of source code, but how did it get there in the first place?”
So in Visual Studio 2012 we have introduced the concept of “key events.” A Key event is a relevant decision or assumption the analyzer made in the process of finding a defect. In the example below there are three key events (on the left). The key event on line 7 explains what the analyzer assumed in order to reach the bug; that the Boolean parameter ‘guard’ is false.
In the Code Analysis window you can click on a warning and step through these key events similar to a traditional debugger.
We have added key events to a handful of the most relevant and common C++ warnings, and as we hear feedback from you we will continue to update and improve the output of the warning messages.
Many Other Improvements
Lastly I would like to mention that there are many other improvements we have made to the accuracy of the C++ analyzer, the source code annotation language used by the analyzer (as well as documentation for it), and the kinds of defects the analyzer finds. Just to point out one improvement; in this release we have added checks for concurrency defects like threading deadlocks and race conditions in C++ code. However, these are topics unto themselves, so we can save them for another day.
In closing this first post for code analysis in Visual Studio 2012, we are excited to use this blog as a way to teach, learn, and interact together. We encourage you to try Visual Studio 2012 and check out code analysis, and we appreciate and look forward to your feedback.
-Code Analysis Team
To discover more about code analysis in Visual Studio 2012 go here:
http://msdn.microsoft.com/en-us/library/windows/apps/hh441471(v=VS.85).aspx
Recently we have received several questions regarding Visual Studio Code Analysis integration with Team Foundation Server’s check-in policy and build server, so I thought it would be helpful to clarify the behavior and expose some relatively hidden functionality.
Source Control Check-in Policy
The first point of confusion that often arises is about the source control check-in policy. A common question is “I have a check-in policy, so why does it let me check-in code that contains code analysis warnings?”, “I want a code analysis check-in policy, but I want to hold different projects (e.g. test and product code) to different standards, can I configure different check-in policies for different projects?”, or “How can I treat warnings as errors so I break the build on code analysis warnings?”
The important thing to note about the code analysis check-in policy is the rule set selected for the check-in policy sets the baseline for the minimum set of rules that must be run on the project before the code can be checked in. All this does is enforce that the rules were run on the project before a check-in, it does not in fact enforce that the code checked-in be code analysis clean for the rule set that is specified in the check-in policy, nor does it actually require that exact rule set be run, as a superset of those rules can be run as long as each rule in the check-in policy rule set was run, the check-in will not be rejected.
The way to prevent checking in code with code analysis warnings is to modify the action for the rules from the default of “Warning” to “Error” for the rule set on the TFS server, setting the build definition trigger to be a “Gated Check-in”, and enabling Code Analysis as part of the build. NOTE: taking this approach will also result in your builds breaking on code analysis warnings since you are treating them as errors.
Rule Sets
The first thing to do is pick the rule set(s) you want run for each project. You can either use the built in rule sets, or create your own custom. You will need to create at least one custom rule set if you want to use the same set of rules, but block check-ins for some projects, and with the same set of rules not block check-ins for other projects. The easiest way to create a custom rule set is to start from an existing rule set:
- Open any project’s properties page
- Select the Code Analysis tab
- Choose the rule set you would like to make a copy of from the rule set drop down
- Click “Open”.

- You will now be presented with the rule set editor, from the rule set editor change the action from “Warning” to “Error”

- When you save the modified rule set you will be presented with the “Save As…” dialogue since the built in rule sets are by default read only
You will now need to either place your new custom rule set on a share and set the project to use that rule set by selecting “<Browse…>” from the rule set dropdown, or you can drop the new custom rule set into the rule set directory (“%VS_INSTALL_DIRECTORY%\Team Tools\Static Analysis Tools\Rule Sets”) on each developer’s machine and the build server machine, and it will automatically appear as an option in the rule set dropdown.
![]()
Configuring the Build Definition
Next we need to configure the build definition:
- Set the “Trigger” to “Gated Check-in”
- Under “Process”, expand “Basic” and set “Perform Code Analysis” to “Always”
That’s it, now check-ins with code analysis warnings will be blocked for projects using the new custom rule set(s).
Version 10.0 of FxCop is the version that ships with Visual Studio 2010 Premium. FxCop 10.0 is part of Version 7.1 of the Microsoft Windows SDK for Windows 7 and .NET Framework 4.
Instructions
- Download the Microsoft Windows SDK for Windows 7 and .NET Framework 4 Version 7.1
- Using elevated privileges execute FxCopSetup.exe from the %ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\FXCop folder.
This blog post applies to Visual Studio 2010 Premium and Ultimate editions. The content was written by Kevin Blasko one of the developers on the Visual Studio Code Analysis team.
The purpose of this blog post is to give you some background on the implementation of the Dataflow Analysis (DFA) rules in Visual Studio 2010.
New Engine, New Rules for Visual Studio 2010
If you looked at the What’s New in Visual Studio 2010 Blog Post you will have noticed that there are several new Code Analysis rules for Managed Code. Several of these new rules are what we describe as DFA rules. These rules are implemented using the Phoenix Code Analysis engine. The rules are:
CA1062 Validate Arguments of Public Methods
CA1303 Do Not Pass Literals as Localized Parameters
CA2000 Dispose Objects Before Losing Scope
CA2100 Review SQL Queries For Security Vulnerabilities
CA2202 Do Not Dispose Objects Multiple Times
CA2204 Literals Should Be Spelled Correctly
CA2215 Dispose Methods Should Call Base Class Dispose
CA2241 Provide Correct Arguments to Formatting Methods
This list of rules should give you an idea of what a DFA engine is capable of.
Why Implement A New Code Analysis Engine?
We needed to implement a new analysis engine to improve the quality and performance of DFA rules. We chose to do this using a technology developed by Microsoft Research called Phoenix. Phoenix is an extensible compiler framework with advanced analysis capabilities. Static analysis turns out to be very important to compilers since the more information you have about the state of the program, the better optimizations you can make when compiling the program. We took advantage of the existing analysis infrastructure as a starting point and built our new engine on top of it. The engine is capable of producing better quality analysis with less noise, less missed analysis, and better performance than our previous DFA engine.
The Phoenix engine excels at analyzing function bodies. Whereas the engine used for the rest of the managed code rules is good at symbolic analysis of class and function definitions (which the Phoenix engine can do as well). For example, consider the following simple example that is actually difficult to analyze without an engine with Phoenix’s capabilities. For the sample, assume that we’re trying to detect violations of CA1062 Validate Arguments of Public Methods.
- public void Function(string argument)
- {
- string localVariable = argument;
- if (localVariable != null)
- {
- Console.WriteLine(argument.Length);
- }
- else
- {
- Console.WriteLine(localVariable.Length);
- }
- }
Looking at “Function”, you can see that line 11 contains a CA1062 violation while line 7 does not, but how can you determine this programmatically? The code will first need to determine which object dereferences could potentially result in a violation. As the assignment on line 3 shows, this isn’t as straight forward as it first appears. In addition to looking for “argument” dereferences, you now need to look for dereferences of “localVariable”.
Now that you’ve found all of the potential dereferences, you need to determine whether or not it’s possible for “argument’s” value to be null for that particular dereference. If you’ve written code that is able to detect that “localVariable” dereferences need to be checked, it probably isn’t that hard to look for null checks against both “argument” and “localVariable”, so the next problem is finding the correct “if” statement that determines whether the dereference is executed. Like before, this is harder than it looks. It’s easy to tell that the dereferences occur within the scope of the “if-else” statement on line 5 and 9 by looking at the code. However, if you’re using an analysis engine whose object model is little more than a wrapper over the raw MSIL, the instructions that you’re analyzing have no concept of scope. The easiest thing that you can do is walk the instructions backwards looking for a branch instruction. But what happens if there’s a branch from further down in the program to line 7 or 11? That branch that you found could turn out to actually be a loop! Or even worse, the author could have inserted a goto that jumps directly to line 7!
Assuming that you get all of the control flow problems sorted out and are able to match the dereference to the branch instruction (maybe you build your own control flow graph or decide that walking the instructions back to the first branch is good enough), you now need to determine if the branch is conditional, and if so, if the condition is a null check. In cases like the one in the example, this will be easy enough, but in many cases, the condition will be the result of a more complex comparison or maybe not even a direct comparison at all. Depending on what you’re willing to accept here, things can get real complicated very fast.
So how does a DFA engine make this easier? The key benefit of a DFA engine is its ability to propagate known information about program state through a method using a control flow graph. New information about the state of the program is then discovered using the information that is known initially. The new information is then fed back into the system and used to further understand the state of the program. The information is propagated by applying a set of rules to the input data depending on the type of MSIL instruction that is being analyzed. This allows you to think about each propagation rule in isolation and only have to worry about what the output is for a narrow and more specific set of inputs.
In the example above, you would have a propagation rule for a compare instruction that takes “localVariable” and “null” as its inputs. Since we know that the literal value for “null” is null, we are able to infer new information about the null-ness of “localVariable” depending on which branch of the “if” statement is taken. As the output of this propagation rule, we would annotate each branch in the control flow graph with the null-ness information that we just inferred. This makes writing the Code Analysis rule simple. All we do is run the null-ness dataflow analysis, look for the dereferences of “argument” (which itself can be done as another dataflow analysis) and then extract the null-ness information for the object being dereferenced.
What Does This Cost Me?
This improved analysis does come at a cost to the Code Analysis user. It turns out that enabling even just one of the DFA rules will approximately double the time it takes to run code analysis. The reason for this is that both the Phoenix engine and the existing (Introspection aka CCI) engine need to load the target assembly and all the references into their own internal representations and then prepare those representations for rule consumption. The good news is that the amount of time it takes to execute all of the DFA rules isn’t that much different than executing one rule. To offset the performance hit, we’ve improved the performance of the Introspection engine so that it runs about 25% faster than the Visual Studio 2008 version.
NOTE: The Phoenix Code Analysis engine and associated DFA rules do not ship in the standalone FxCop release.
This blog explains how to implement your own static code analysis rules for analyzing your .NET (C#, VB.NET, etc) code. The material was written by Todd King, one of the developers on the Visual Studio Code Analysis team.
NOTE: Writing custom FxCop rules, the associated APIs and the process for installing them is not a supported feature of the product. We are providing this information because we get so many questions about how to do it.
Prerequisites
You must be using Visual Studio 2010 Premium or Visual Studio 2010 Ultimate to implement custom code analysis rules.
Creating the MyCustomRules project
NOTE: If you already have an existing custom rules project you can skip this step.
-
Create a new class library project and name it whatever you want your rules assembly to be named. For the purposes of this blog I’ve named it MyCustomRules.
-
Next add a reference to the FxCop assemblies. Your custom rules project will need to reference FxCopSdk.dll and Microsoft.Cci.dll. Visual Studio 2010 installs the assemblies in “C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop” on a 32-bit OS and “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop” on a 64-bit OS. In order to avoid path resolution issues when the project is built on different computers you can use the $(CodeAnalysisPath) MSBuild property. The property will resolve to the location where the FxCop assemblies have been installed. Use the following procedure to define the references to the two assemblies
-
Open up your project in Visual Studio 2010.
-
In Solution Explorer right click on the project and select Unload Project
-
Now right click on the project and select edit MyCustomRules.csproj
-
Find the ItemGroup xml element where your project’s references are and add the first two <Reference> elements described in the following code snippet
- <ItemGroup>
- <Reference Include="FxCopSdk">
- <HintPath>$(CodeAnalysisPath)\FxCopSdk.dll</HintPath>
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.Cci">
- <HintPath>$(CodeAnalysisPath)\Microsoft.Cci.dll</HintPath>
- <Private>False</Private>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
-
Close the editor, right click on the project and select Reload Project.
-
-
Now we need to setup the RuleMetadata.xml file for this project. The RuleMetadata.xml file is where various properties of the rules for this project will be stored. For example this is where the rule description, resolutions, message level, owner contact info, etc is stored.
-
To Add a RuleMetadata.xml file right click on your project and select add new item.
-
Type XML File in the Search Installed Templates control.
-
Select the XML File template and name it RuleMetadata.xml (it can be named whatever you want, for the purposes of this blog I’ve named it RuleMetadata.xml).
-
-
At this point you don’t have any rules so all you need to do is add a root Rules element as follows. Where the FriendlyName value is some user readable string that will be displayed to the user as the name of your rules assembly.
- <?xml version="1.0" encoding="utf-8" ?>
- <Rules FriendlyName="My Custom FxCop Rules">
-
-
Next set the RuleMetadata.xml file as an EmbeddedResource for our rules assembly
-
In Solution Explorer right click on the file RuleMetadata.xml and select Properties
-
In the Property Tool window change the Build Action property to Embedded Resource.
-
Implementing a custom rule
Note that we have not released an SDK for implementing custom rules, so the API is undocumented and will almost certainly change in the future. With those caveats in mind, the following example describes how to implement a simple rule. The rule we will implement checks whether or not the identifiers for private and internal fields use Hungarian notation.
1. Define an abstract class that inherits from the FxCop API and initializes the resources defined in the XML file.
- using Microsoft.FxCop.Sdk;
- namespace MyCustomFxCopRules
- {
- internal abstract class BaseFxCopRule : BaseIntrospectionRule
- {
- protected BaseFxCopRule(string ruleName)
- : base(ruleName, "DukesFirstFxCopRule.DukesFirstFxCopRule", typeof(BaseFxCopRule).Assembly)
- { }
- }
- }
Where the resource name is the default namespace of your project + whatever you named the RuleMetadata.xml file. "MyCustomFxCopRules.RuleMetadata" in the example above.
NOTE: Make sure you use the default namespace for your project in the resource name. If you do not FxCopCmd.exe will return error CA0054 because it is unable to load your rule.
2. Define a class to implement the rule and derive from our previously defined class.
- internal sealed class EnforceHungarianNotation : BaseFxCopRule
- {
- public EnforceHungarianNotation()
- : base("EnforceHungarianNotation")
- { }
- }
3. Define the visibility of the code elements we want to analyze by overriding the TargetVisibility property. Normally it is fine to leave this at the default implementation of TargetVisibilities.All however in this case we only want to analyze fields that are not externally visible so we want to return a value of TargetVisibilities.NotExternallyVisible. Add the following code to the EnforceHungarianNotation class definition.
- // Only fire on non-externally visible code elements.
- public override TargetVisibilities TargetVisibility
- {
- get
- {
- return TargetVisibilities.NotExternallyVisible;
- }
- }
4. Since this rule is supposed to fire on fields, which are members of types, we override the Check(Member) method. We need to verify that the member being examined by the check method is actually a field. This could be done either by trying to cast it to a Microsoft.FxCop.Sdk.Field type or checking if the member’s NodeType is NodeType.Field. Once we know we are looking at a field we need to determine if it is a static field or not so we know which kind of Hungarian prefix should be expected. To do this we can check the IsStatic property on the field. Now we just need to determine if the field’s name starts with the expected Hungarian notation prefix and if not report a rule violation. To do this we get the field’s name using the Name property (actually need to call Name.Name to get the string form of the name, just one of the quirks of the current API) and check if it starts with the expected prefix. If not then we need to construct a Problem object and add it to the rule’s ProblemCollection accessed through the inherited Problems property. Add the following code to the EnforceHungarianNotation class definition.
- public override ProblemCollection Check(Member member)
- {
- Field field = member as Field;
- if (field == null)
- {
- // This rule only applies to fields.
- // Return a null ProblemCollection so no violations are reported for this member.
- return null;
- }
- if (field.IsStatic)
- {
- CheckFieldName(field, s_staticFieldPrefix);
- }
- else
- {
- CheckFieldName(field, s_nonStaticFieldPrefix);
- }
- // By default the Problems collection is empty so no violations will be reported
- // unless CheckFieldName found and added a problem.
- return Problems;
- }
- private const string s_staticFieldPrefix = "s_";
- private const string s_nonStaticFieldPrefix = "m_";
5. Rule resolutions are stored in the RuleMetadata.xml file. Calling GetResolution will retrieve that resolution string and also fill in any string arguments passed in. Finally we need to create a Problem object from the Resolution object we just created and add that Problem to the Problems collection for this rule. Add the following code to the EnforceHungarianNotation class definition.
- private void CheckFieldName(Field field, string expectedPrefix)
- {
- if (!field.Name.Name.StartsWith(expectedPrefix, StringComparison.Ordinal))
- {
- Resolution resolution = GetResolution(
- field, // Field {0} is not in Hungarian notation.
- expectedPrefix // Field name should be prefixed with {1}.
- );
- Problem problem = new Problem(resolution);
- Problems.Add(problem);
- }
- }
6. The final step is adding the appropriate rule metadata for this new rule to the RuleMetadata.xml file in our project. The following rule metadata can be defined in the RuleMetadata file.
- Display name of the rule.
- Rule description.
- One or more rule resolutions.
- The MessageLevel (severity) of the rule. This can be set to one of the following:
- CriticalError
- Error
- CriticalWarning
- Warning
- Information
-
- The certainty of the violation. This field represents the accuracy percentage of the rule. In other words this field describes the rule author’s confidence in how accurate this rule is.
- The FixCategory of this rule. This field describes if fixing this rule would require a breaking change, ie a change that could break other assemblies referencing the one being analyzed.
- The help url for this rule.
- The name of the owner of this rule.
- The support email to contact about this rule.
For the example EnforceHungarianNotation rule described in this sample the RuleMetadata.xml file should look something like:
- <?xml version="1.0" encoding="utf-8" ?>
- <Rules FriendlyName="My Custom FxCop Rules">
- <Rule TypeName="EnforceHungarianNotation" Category="MyRules" CheckId="CR1000">
- <Name>Enforce Hungarian Notation</Name>
- <Description>Checks fields for compliance with Hungarian notation.</Description>
- <Resolution>Field {0} is not in Hungarian notation. Field name should be prefixed with '{1}'.</Resolution>
- <MessageLevel Certainty="100">Warning</MessageLevel>
- <FixCategories>NonBreaking</FixCategories>
- <Url />
- <Owner />
- <Email />
- </Rule>
- </Rules>
NOTE: The TypeName attribute of the Rule element must match exactly with the name string passed in to the base constructor of the rule implementation. If they do not match FxCopCmd.exe will return error CA0054 because it is unable to load your rule.
Debugging custom rules
You can debug custom rules through FxCopCmd.exe. Normally you would run your rule against another project. To simplify the instructions in this blog we’re going to run our new rule against the implementation of the rule itself. In the project properties for your custom rules project on the Debug tab do the following
1. Configure the project to launch an external program and enter in the path to FxCopCmd.exe. For example
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe
2. For command line arguments specify
/out:"results.xml" /file:"MyCustomRules.dll" /rule:"MyCustomRules.dll" /D:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop"
3. Set the working directory to the build output folder. For example
C:\Projects\MyCustomRules\MyCustomRules\bin\Debug\
Now you can to debug your custom rules by simply hitting F5 from your custom rules project. Try it
1. Set a breakpoint on the statement
- if (!field.Name.Name.StartsWith(expectedPrefix, StringComparison.Ordinal))
2. Press F5 and execution should stop at the breakpoint.
3. Press F5 again and execution should complete successfully.
4. Note that there is not a results.xml file in the …\Debug folder because there are no rule violations in the code we are running the rule against.
Let’s create a rule violation so we can verify that our rule is behaving as it should.
1. Add the following code to the EnforceHungarianNotation class definition
- private static int m_Foo;
2. Press F5
3. Disable the breakpoint and Press F5 again
4. Examine the results.xml file in the …\Debug folder. Note the description of the rule violation. It works!
Running custom rules
At this point we have verified that our rule functions as expected. To run our custom rule using the command line utility FxCopCmd simply use the command line options we defined in the Debug options. Run FxCopCmd.exe /? For a list of all the command line utility’s options.
A new feature in Visual Studio 2010 is called rule sets. Rule sets are a new way of configuring which rules should be run during analysis. The easiest way to integrate your rules into Visual Studio 2010 is to copy them to the %Program Files%\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\Rules directory. If you are replacing an existing assembly you will need to restart Visual Studio after copying the file. Once the file is copied to the Rules directory the next time you launch the rule set editor you should see your custom rules. Try the following procedure
1. From your project’s property settings select the Code Analysis tab
2. Click on the Open button to open the Rule Set editor
3. Create a custom rule set by doing a File à Save As and saving the rule set to MyCustomRuleSet.ruleset
4. Click on the button Show rules that are not enabled in the rule set editor’s button bar. Your custom rule(s) should appear in the list.
If you don’t want to mess with your Visual Studio installation by adding your own custom rules to the built in Rules directory that Visual Studio uses, you can manually edit a custom rule set instead.
1. Create a new rule set and save it.
2. Open that new rule set file in a text or xml editor and add a RuleHintPaths section with a Path element with the location of your custom rules. The path to your custom rules can include absolute file paths, relative paths, and use environment variables. For example your rule set file might look like the following:
- <?xml version="1.0" encoding="utf-8"?>
- <RuleSet Name="My Custom Rule Set" Description=" " ToolsVersion="10.0">
- <RuleHintPaths>
- <Path>%CustomRulesPath%</Path>
- <Path>..\..\CustomRules</Path>
- <Path>C:\CustomRules</Path>
- </RuleHintPaths>
- </RuleSet>
3. Now open that rule set file with the visual studio Code Analysis Rule Set Editor (the default editor for *.ruleset files). Your custom rules should appear in the editor as seen above.
Troubleshooting Visual Studio integration
If code analysis is reporting errors performing analysis due to exceptions, more details on those exceptions can be found in the *.CodeAnalysisLog.xml file in the bin directory of the assembly being analyzed (see the Exceptions section of the report file towards the bottom).
When you run code analysis from Visual Studio the FxCopCmd command line utility is invoked to perform the analysis. To discover exactly what command line options are being passed to FxCopCmd by Visual Studio so you can reproduce and debug the error outside of Visual Studio, first set the build output verbosity to Normal or higher. This can be done by going to Tools - >Options -> Projects and Solutions -> Build and Run.
Run code analysis and view the output window. You should see the exact command line arguments passed into FxCopCmd right after the “Running Code Analysis…” message.
For more information on where FxCopCmd is looking for assemblies you may increase the trace level of FxCopCmd to 3. This can be done by modifying the FxCopCmd.exe.config file in the same directory as FxCopCmd.exe as follows
- <switches>
- <!--
- TraceSwitch has the following values
- Off = 0, Error = 1, Warning = 2, Info = 3, Verbose = 4
- BooleanSwitch has the following values
- Off = 0, On = 1
- -->
- <!-- TraceSwitch'es -->
- <add name="Trace" value="3" />
- <!-- BooleanSwitch'es -->
- <add name="TraceExceptions" value="0" />
- </switches>
Once this is done the xml reports (like the *.CodeAnalysisLog.xml file mentioned earlier) produced by FxCopCmd will contain a DebugInfo section that details what search paths FxCopCmd used and exactly where it resolved each assembly reference to. This information can also be determined by examining the trace messages emitted by FxCopCmd to the console.
This blog compares the Code Analysis warnings and errors generated by Visual Studio 2008 and Visual Studio 2010.
Managed Code Analysis
| Warning / Error Number | Description | Visual Studio 2008 Team System | Visual Studio 2010 Premium |
| An exception was raised within managed code analysis tool that does not indicate an expected error condition. | Yes | Yes | |
| No rules were selected. | Yes | Yes | |
| No targets were selected to analyze. | Yes | Yes | |
| Rule assembly could not be loaded. | Yes | Yes | |
| A custom rule assembly has invalid XML resources. | Yes | Yes | |
| Could not load file:<path> | Yes | Yes | |
| A project file has an incorrect version of the analysis tool. | Yes | Yes | |
| Violations cannot be mapped to the current set of targets and rules. | Yes | Yes | |
| Unable to load assemblies referenced. | Yes | Yes | |
| Command line switch error. | Yes | Yes | |
| Unable to load assemblies referenced indirectly. | Yes | Yes | |
| The rule 'RuleId' referenced in rule set 'RuleSetName' could not be found. | - | Yes | |
| The rule 'RuleId' could not be found. | - | Yes | |
| Failed to load rule set file or one of its dependent rule set files. | - | Yes | |
| No analysis was performed because the specified rule set did not contain any FxCop rules. | - | Yes | |
| Unsupported metadata construct: Type 'TypeName' contains both a property and a field with the same name 'PropertyFieldName' | - | Yes | |
| CA0066 | - | Yes | |
| Directory not found. | - | Yes | |
| Debug information could not be found for target assembly 'AssemblyName'. | - | Yes | |
| UsingAlternatePlatform. FrameworkVersion1 could not be found. Using FrameworkVersion2 instead. For best analysis results please ensure that the correct .NET Framework is installed. | - | Yes | |
| Unable to analyze permission attributes | - | Yes | |
| Unable to read output report. | Yes | Yes | |
| Unsupported language. | Yes | Yes | |
| Additional warnings cannot be displayed. | Yes | Yes | |
| Rule directory was ignored because it does not exist | - | Yes | |
| The property is deprectated. Use the superceding property | - | Yes | |
| Do not declare static members on generic types | Yes | Yes | |
| Types that own disposable fields should be disposable | Yes | Yes | |
| Do not expose generic lists | Yes | Yes | |
| Use generic event handler instances | Yes | Yes | |
| Generic methods should provide type parameter | Yes | Yes | |
| Avoid excessive parameters on generic types | Yes | Yes | |
| Do not nest generic types in member signatures | Yes | Yes | |
| Use generics where appropriate | Yes | Yes | |
| Enums should have zero value | Yes | Yes | |
| Declare event handlers correctly | Yes | Yes | |
| Collections should implement generic interface | Yes | Yes | |
| Consider passing base types as parameters | Yes | Yes | |
| Abstract types should not have constructors | Yes | Yes | |
| Overload operator equals on overloading add and subtract | Yes | Yes | |
| Mark assemblies with CLSCompliantAttribute | Yes | Yes | |
| Mark assemblies with AssemblyVersionAttribute | Yes | Yes | |
| Mark assemblies with ComVisibleAttribute | Yes | Yes | |
| Mark attributes with AttributeUsageAttribute | Yes | Yes | |
| Define accessors for attribute arguments | Yes | Yes | |
| Avoid namespaces with few types | Yes | Yes | |
| Avoid out parameters | Yes | Yes | |
| Indexers should not be multidimensional | Yes | Yes | |
| Use properties where appropriate | Yes | Yes | |
| Replace repetitive arguments with params array | Yes | Yes | |
| Default parameters should not be used | Yes | Yes | |
| Mark enums with FlagsAttribute | Yes | Yes | |
| Enum storage should be Int32 | Yes | Yes | |
| Use events where appropriate | Yes | Yes | |
| Do not catch general exception types | Yes | Yes | |
| Implement standard exception constructors | Yes | Yes | |
| Interface methods should be callable by child types | Yes | Yes | |
| Nested types should not be visible | Yes | Yes | |
| ICollection implementations have strongly typed members | Yes | Yes | |
| Override methods on comparable types | Yes | Yes | |
| Enumerators should be strongly typed | Yes | Yes | |
| Lists are strongly typed | Yes | Yes | |
| Avoid empty interfaces | Yes | Yes | |
| Provide ObsoleteAttribute message | Yes | Yes | |
| Use integral or string argument for indexers | Yes | Yes | |
| Properties should not be write only | Yes | Yes | |
| Do not pass types by reference | Yes | Yes | |
| Do not overload operator equals on reference types | Yes | Yes | |
| Do not declare protected members in sealed types | Yes | Yes | |
| Do not declare virtual members in sealed types | Yes | Yes | |
| Types that own native resources should be disposable | Yes | Yes | |
| Declare types in namespaces | Yes | Yes | |
| Do not declare visible instance fields | Yes | Yes | |
| Static holder types should be sealed | Yes | Yes | |
| Static holder types should not have constructors | Yes | Yes | |
| URI parameters should not be strings | Yes | Yes | |
| URI return values should not be strings | Yes | Yes | |
| URI properties should not be strings | Yes | Yes | |
| String URI overloads call System.Uri overloads | Yes | Yes | |
| Types should not extend certain base types | Yes | Yes | |
| Members should not expose certain concrete types | Yes | Yes | |
| Move P/Invokes to NativeMethods class | Yes | Yes | |
| Do not hide base class methods | Yes | Yes | |
| Validate arguments of public methods | - | Yes | |
| Implement IDisposable correctly | Yes | Yes | |
| Exceptions should be public | Yes | Yes | |
| Do not raise exceptions in unexpected locations | Yes | Yes | |
| Specify MessageBoxOptions | Yes | Yes | |
| Avoid duplicate accelerators | Yes | Yes | |
| Do not hardcode locale specific strings | Yes | Yes | |
| Do not pass literals as localized parameters | - | Yes | |
| Specify CultureInfo | Yes | Yes | |
| Specify IFormatProvider | Yes | Yes | |
| Set locale for data types | Yes | Yes | |
| Specify StringComparison | Yes | Yes | |
| Normalize strings to uppercase | Yes | Yes | |
| Use ordinal StringComparison | Yes | Yes | |
| P/Invoke entry points should exist | Yes | Yes | |
| P/Invokes should not be visible | Yes | Yes | |
| Avoid overloads in COM visible interfaces | Yes | Yes | |
| Auto layout types should not be COM visible | Yes | Yes | |
| Call GetLastError immediately after P/Invoke | Yes | Yes | |
| COM visible type base types should be COM visible | Yes | Yes | |
| Avoid Int64 arguments for Visual Basic 6 clients | Yes | Yes | |
| Avoid static members in COM visible types | Yes | Yes | |
| Do not use AutoDual ClassInterfaceType | Yes | Yes | |
| Com visible types should be creatable | Yes | Yes | |
| COM registration methods should be matched | Yes | Yes | |
| COM registration methods should not be visible | Yes | Yes | |
| Mark ComSource interfaces as IDispatch | Yes | Yes | |
| Avoid non-public fields in COM visible value types | Yes | Yes | |
| Mark boolean P/Invoke arguments with MarshalAs | Yes | Yes | |
| Declare P/Invokes correctly | Yes | Yes | |
| Variable names should not match field names | Yes | Yes | |
| Variable names should not match field names | Yes | Yes | |
| Avoid excessive inheritance | Yes | Yes | |
| Avoid excessive inheritance | Yes | Yes | |
| Avoid excessive complexity | Yes | Yes | |
| Avoid excessive complexity | Yes | Yes | |
| Review misleading field names | Yes | Yes | |
| Review misleading field names | Yes | Yes | |
| Avoid unmaintainable code | Yes | Yes | |
| Avoid unmaintainable code | Yes | Yes | |
| Avoid excessive class coupling | Yes | Yes | |
| Avoid excessive class coupling | Yes | Yes | |
| Do not use idle process priority | Yes | Yes | |
| Do not use timers that prevent power state changes | Yes | Yes | |
| Do not name enum values 'Reserved' | Yes | Yes | |
| Resource string compound words should be cased correctly | Yes | Yes | |
| Compound words should be cased correctly | Yes | Yes | |
| Resource strings should be spelled correctly | Yes | Yes | |
| Identifiers should be spelled correctly | Yes | Yes | |
| Identifiers should not contain underscores | Yes | Yes | |
| Identifiers should differ by more than case | Yes | Yes | |
| Identifiers should be cased correctly | Yes | Yes | |
| Identifiers should have correct suffix | Yes | Yes | |
| Identifiers should not have incorrect suffix | Yes | Yes | |
| Do not prefix enum values with type name | Yes | Yes | |
| Events should not have before or after prefix | Yes | Yes | |
| Flags enums should have plural names | Yes | Yes | |
| Identifiers should have correct prefix | Yes | Yes | |
| Identifiers should not match keywords | Yes | Yes | |
| Only FlagsAttribute enums should have plural names | Yes | Yes | |
| Parameter names should not match member names | Yes | Yes | |
| Identifiers should not contain type names | Yes | Yes | |
| Property names should not match get methods | Yes | Yes | |
| Identifiers should not have incorrect prefix | Yes | Yes | |
| Type names should not match namespaces | Yes | Yes | |
| Parameter names should match base declaration | Yes | Yes | |
| Use preferred terms | Yes | Yes | |
| Do not cast unnecessarily | Yes | Yes | |
| Review unused parameters | Yes | Yes | |
| Use literals where appropriate | Yes | Yes | |
| Remove unused locals | Yes | Yes | |
| Do not initialize unnecessarily | Yes | No | |
| Do not ignore method results | Yes | Yes | |
| Avoid excessive locals | Yes | Yes | |
| Initialize reference type static fields inline | Yes | Yes | |
| Avoid uncalled private code | Yes | Yes | |
| Avoid uninstantiated internal classes | Yes | Yes | |
| Avoid unsealed attributes | Yes | Yes | |
| Prefer jagged arrays over multidimensional | Yes | Yes | |
| Override equals and operator equals on value types | Yes | Yes | |
| Call GC.SuppressFinalize correctly | Yes | Yes | |
| Properties should not return arrays | Yes | Yes | |
| Test for empty strings using string length | Yes | Yes | |
| Remove empty finalizers | Yes | Yes | |
| Mark members as static | Yes | Yes | |
| Avoid unused private fields | Yes | Yes | |
| Mark assemblies with NeutralResourcesLanguageAttribute | Yes | Yes | |
| Value type fields should be portable | Yes | Yes | |
| P/Invoke declarations should be portable | Yes | Yes | |
| Use only API from targeted framework | Yes | Yes | |
| Dispose objects before losing scope | - | Yes | |
| Avoid calling problematic methods | Yes | Yes | |
| Do not lock on objects with weak identity | Yes | Yes | |
| Do not treat fibers as threads | Yes | Yes | |
| Remove calls to GC.KeepAlive | Yes | Yes | |
| Use SafeHandle to encapsulate native resources | Yes | Yes | |
| Review SQL queries for security vulnerabilities | - | Yes | |
| Specify marshaling for P/Invoke string arguments | Yes | Yes | |
| Catch non-CLSCompliant exceptions in general handlers | Yes | Yes | |
| Review imperative security | Yes | Yes | |
| Do not declare read only mutable reference types | Yes | Yes | |
| Array fields should not be read only | Yes | Yes | |
| Secure asserts | Yes | Yes | |
| Review deny and permit only usage | Yes | Yes | |
| Review declarative security on value types | Yes | Yes | |
| Review visible event handlers | Yes | Yes | |
| Pointers should not be visible | Yes | Yes | |
| Secured types should not expose fields | Yes | Yes | |
| Method security should be a superset of type | Yes | Yes | |
| Call GC.KeepAlive when using native resources | Yes | Yes | |
| APTCA methods should only call APTCA methods | Yes | Yes | |
| APTCA types should only extend APTCA base types | Yes | Yes | |
| Review SuppressUnmanagedCodeSecurityAttribute usage | Yes | Yes | |
| Seal methods that satisfy private interfaces | Yes | Yes | |
| Secure serialization constructors | Yes | Yes | |
| Static constructors should be private | Yes | Yes | |
| Do not indirectly expose methods with link demands | Yes | Yes | |
| Override link demands should be identical to base | Yes | Yes | |
| Wrap vulnerable finally clauses in outer try | Yes | Yes | |
| Type link demands require inheritance demands | Yes | Yes | |
| Security transparent assemblies should not contain security critical code | Yes | No | |
| Security transparent code should not assert | Yes | No | |
| Security transparent code should not reference non-public security critical members | Yes | No | |
| Security critical constants should be transparent | - | Yes | |
| Security critical types may not participate in type equivalence | - | Yes | |
| Default constructors must be at least as critical as base type default constructors | - | Yes | |
| Delegates must bind to methods with consistent transparency | - | Yes | |
| Methods must keep consistent transparency when overriding base methods | - | Yes | |
| Level 2 assemblies should not contain LinkDemands | - | Yes | |
| Members should not have conflicting transparency annotations | - | Yes | |
| Transparent methods must contain only verifiable IL | - | Yes | |
| Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attribute | - | Yes | |
| Transparent methods may not use the HandleProcessCorruptingExceptions attribute | - | Yes | |
| Transparent code must not reference security critical items | - | Yes | |
| Transparent methods must not satisfy LinkDemands | - | Yes | |
| Transparent code should not be protected with LinkDemands | - | Yes | |
| Transparent methods should not use security demands | - | Yes | |
| Transparent code should not load assemblies from byte arrays | - | Yes | |
| Transparent methods should not be decorated with the SuppressUnmanagedCodeSecurityAttribute | - | Yes | |
| Types must be at least as critical as their base types and interfaces | - | Yes | |
| Transparent methods may not use security asserts | - | Yes | |
| Transparent methods must not call native code | - | Yes | |
| Rethrow to preserve stack details | Yes | Yes | |
| Do not raise reserved exception types | Yes | Yes | |
| Do not dispose objects multiple times | - | Yes | |
| Literals should be spelled correctly | - | Yes | |
| Use managed equivalents of Win32 API | Yes | Yes | |
| Initialize value type static fields inline | Yes | Yes | |
| Instantiate argument exceptions correctly | Yes | Yes | |
| Assemblies should have valid strong names | Yes | Yes | |
| Non-constant fields should not be visible | Yes | Yes | |
| Do not mark serviced components with WebMethod | Yes | Yes | |
| Disposable fields should be disposed | Yes | Yes | |
| Do not call overridable methods in constructors | Yes | Yes | |
| Dispose methods should call base class dispose | - | Yes | |
| Disposable types should declare finalizer | Yes | Yes | |
| Do not mark enums with FlagsAttribute | Yes | Yes | |
| Override GetHashCode on overriding Equals | Yes | Yes | |
| Do not raise exceptions in exception clauses | Yes | Yes | |
| Finalizers should call base class finalizer | Yes | Yes | |
| Finalizers should be protected | Yes | Yes | |
| Do not decrease inherited member visibility | Yes | Yes | |
| Members should differ by more than return type | Yes | Yes | |
| Override equals on overloading operator equals | Yes | Yes | |
| Operator overloads have named alternates | Yes | Yes | |
| Operators should have symmetrical overloads | Yes | Yes | |
| Collection properties should be read only | Yes | Yes | |
| Do not ship unreleased resource formats | Yes | Yes | |
| Implement serialization constructors | Yes | Yes | |
| Use params for variable arguments | Yes | Yes | |
| Overload operator equals on overriding ValueType.Equals | Yes | Yes | |
| Mark Windows Forms entry points with STAThread | Yes | Yes | |
| Operations should not overflow | Yes | Yes | |
| Pass System.Uri objects instead of strings | Yes | Yes | |
| Mark all non-serializable fields | Yes | Yes | |
| Call base class methods on ISerializable types | Yes | Yes | |
| Mark ISerializable types with SerializableAttribute | Yes | Yes | |
| Implement serialization methods correctly | Yes | Yes | |
| Provide deserialization methods for optional fields | Yes | Yes | |
| Implement ISerializable correctly | Yes | Yes | |
| Provide correct arguments to formatting methods | - | Yes | |
| Test for NaN correctly | Yes | Yes | |
| Attribute string literals should parse correctly | Yes | Yes |
FxCopCmd Errors
No changes between Visual Studio 2008 and Visual Studio 2010.
| Warning / Error Number | Description | Visual Studio Team System 2008 | Visual Studio 2010 Premium |
| 0x0 | No errors | Yes | Yes |
| 0x1 | Analysis error | Yes | Yes |
| 0x2 | Rule exceptions | Yes | Yes |
| 0x4 | Project load error | Yes | Yes |
| 0x8 | Assembly load error | Yes | Yes |
| 0x10 | Rule library load error | Yes | Yes |
| 0x20 | Import report load error | Yes | Yes |
| 0x40 | Output error | Yes | Yes |
| 0x80 | Command line switch error | Yes | Yes |
| 0x100 | Initialization error | Yes | Yes |
| 0x200 | Assembly references error | Yes | Yes |
| 0x400 | BuildBreakingMessage | Yes | Yes |
| 0x1000000 | Unknown error | Yes | Yes |
C/C++ Code Analysis
No changes between Visual Studio 2008 and Visual Studio 2010.
| Warning / Error Number | Description | Visual Studio Team System 2008 | Visual Studio 2010 Premium |
| using uninitialized memory <variable> | Yes | Yes | |
| dereferencing NULL pointer <name> | Yes | Yes | |
| possible buffer overrun in call to <function>: use of unchecked value | Yes | Yes | |
| return value ignored: <function> could return unexpected value | Yes | Yes | |
| call to <function> may not zero-terminate string <variable> | Yes | Yes | |
| string <variable> may not be zero-terminated | Yes | Yes | |
| buffer overrun due to number of characters/number of bytes mismatch in call to <function> | Yes | Yes | |
| Incorrect length parameter in call to <function>. Pass the number of remaining characters, not the buffer size of <variable> | Yes | Yes | |
| missing string argument to <function> corresponding to conversion specifier <number> | Yes | Yes | |
| missing integer argument to <function> corresponding to conversion specifier <number> | Yes | Yes | |
| non-pointer passed as parameter <number> when pointer is required in call to <function> | Yes | Yes | |
| parameter <number> in call to <function> must be the address of the string | Yes | Yes | |
| index <name> is out of valid index range <min> to <max> for non-stack buffer <variable> | Yes | Yes | |
| buffer overrun for <variable>, which is possibly stack allocated: index <name> is out of valid index range <min> to <max> | Yes | Yes | |
| buffer overrun for <variable>, which is possibly stack allocated, in call to <function>: length <size> exceeds buffer size <max> | Yes | Yes | |
| buffer overrun for buffer <variable> in call to <function>: length <size> exceeds buffer size | Yes | Yes | |
| possible buffer overrun in call to <function>: use of unchecked parameter <variable> | Yes | Yes | |
| using 'sizeof<variable1>' as parameter <number> in call to <function> where <variable2> may be an array of wide characters, did you intend to use character count rather than byte count? | Yes | Yes | |
| Leaking memory <pointer> due to an exception. Consider using a local catch block to clean up memory | Yes | Yes | |
| cast between semantically different integer types: HRESULT to a Boolean type | Yes | Yes | |
| cast between semantically different integer types: a Boolean type to HRESULT | Yes | Yes | |
| compiler-inserted cast between semantically different integral types: a Boolean type to HRESULT | Yes | Yes | |
| Implicit cast between semantically different integer types: testing HRESULT with 'not'. Consider using SUCCEEDED or FAILED macro instead | Yes | Yes | |
| Implicit cast between semantically different integer types: comparing HRESULT to 1 or TRUE. Consider using SUCCEEDED or FAILED macro instead | Yes | Yes | |
| warning C6220 - Implicit cast between semantically different integer types: comparing HRESULT to -1. Consider using SUCCEEDED or FAILED macro instead | Yes | Yes | |
| Implicit cast between semantically different integer types: comparing HRESULT to an integer. Consider using SUCCEEDED or FAILED macros instead | Yes | Yes | |
| Implicit cast between semantically different integer types: assigning 1 or TRUE to HRESULT. Consider using S_FALSE instead | Yes | Yes | |
| Implicit cast between semantically different integer types: assigning -1 to HRESULT. Consider using E_FAIL instead | Yes | Yes | |
| implicit cast between semantically different integer types: using HRESULT in a Boolean context | Yes | Yes | |
| (<non-zero constant> || <expression>) is always a non-zero constant | Yes | Yes | |
| (<expression> || <non-zero constant>) is always a non-zero constant | Yes | Yes | |
| (<zero> && <expression>) is always zero. <expression> is never evaluated and may have side effects | Yes | Yes | |
| (<non-zero constant> && <expression>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator? | Yes | Yes | |
| (<expression> && <non-zero constant>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator? | Yes | Yes | |
| A jump out of this try-block forces local unwind. Incurs severe performance penalty | Yes | Yes | |
| local declaration of <variable> hides previous declaration at <line> of <file> | Yes | Yes | |
| Local declaration of <variable> hides declaration of same name in outer scope. Additional Information: See previous declaration at <location>. | Yes | Yes | |
| setting a SECURITY_DESCRIPTOR’s DACL to NULL will result in an unprotected object | Yes | Yes | |
| Calling <function> VirtualFree without the MEM_RELEASE flag may free memory but not address descriptors (VADs); results in address space leaks | Yes | Yes | |
| _alloca indicates failure by raising a stack overflow exception. Consider using _alloca_s instead | Yes | Yes | |
| using TerminateThread does not allow proper thread clean up | Yes | Yes | |
| labeled code is unreachable: (<expression> & <constant>) in switch-expr cannot evaluate to <case-label> | Yes | Yes | |
| sizeof * sizeof is almost always wrong, did you intend to use a character count or a byte count? | Yes | Yes | |
| Function uses <constant> bytes of stack: exceeds /analyze:stacksize<constant>. Consider moving some data to heap | Yes | Yes | |
| using _alloca in a loop; this can quickly overflow stack | Yes | Yes | |
| Incorrect order of operations: (<TYPE1>)(<TYPE2>)x + y. Possible missing parentheses in (<TYPE1>)((<TYPE2>)x + y) | Yes | Yes | |
| possible incorrect order of operations: dereference ignored | Yes | Yes | |
| missing float argument to <function>: add a float argument corresponding to conversion specifier <number> | Yes | Yes | |
| extra argument passed to <function>: parameter <number> is not used by the format string | Yes | Yes | |
| non-float passed as argument <number> when float is required in call to <function> | Yes | Yes | |
| warning 6273 - non-integer passed as parameter <number> when integer is required in call to <function>: if a pointer value is being passed, %p should be used | Yes | Yes | |
| non-character passed as parameter <number> when character is required in call to <function> | Yes | Yes | |
| Cast between semantically different string types: char* to wchar_t*. Use of invalid string can lead to undefined behavior | Yes | Yes | |
| NULL application name with an unquoted path in call to <function>: results in a security vulnerability if the path contains spaces | Yes | Yes | |
| <variable> is allocated with array new [], but deleted with scalar delete. Destructors will not be called | Yes | Yes | |
| <variable> is allocated with scalar new, deleted with array delete [] | Yes | Yes | |
| <variable> is allocated with <function>, but deleted with <function> | Yes | Yes | |
| warning 6281 - incorrect order of operations: relational operators have higher precedence than bitwise operators | Yes | Yes | |
| Incorrect operator: assignment of constant in Boolean context. Consider using '==' instead | Yes | Yes | |
| <variable> is allocated with array new [], but deleted with scalar delete | Yes | Yes | |
| object passed as parameter '%d' when string is required in call to <function>. | Yes | Yes | |
| (<non-zero constant> || <non-zero constant>) is always a non-zero constant. Did you intend to use the bitwise-and operator? | Yes | Yes | |
| (<non-zero constant> || <expression>) is always a non-zero constant. <expression> is never evaluated and may have side effects | Yes | Yes | |
| redundant code: the left and right sub-expressions are identical | Yes | Yes | |
| Incorrect operator: mutual inclusion over && is always zero. Did you intent to use || instead? | Yes | Yes | |
| Incorrect operator: mutual exclusion over || is always a non-zero constant. Did you intend to use && instead? | Yes | Yes | |
| Bitwise operation on logical result: ! has higher precedence than &. Use && or (!(x & y)) instead | Yes | Yes | |
| Bitwise operation on logical result: ! has higher precedence than |. Use || or (!(x | y)) instead | Yes | Yes | |
| ill-defined for-loop: counts up from maximum | Yes | Yes | |
| Ill-defined for-loop: counts down from minimum | Yes | Yes | |
| Ill-defined for-loop: initial condition does not satisfy test. Loop body not executed | Yes | Yes | |
| Ill-defined for-loop: <variable> values are of the range "min" to "max". Loop executed indefinitely | Yes | Yes | |
| Ill-defined for-loop: Loop body only executed once | Yes | Yes | |
| Arithmetic overflow: 32-bit value is shifted, then cast to 64-bit value. Result may not be an expected value | Yes | Yes | |
| using a read-only string <pointer> as a writable string argument: this will attempt to write into static read-only memory and cause random crashes | Yes | Yes | |
| explicitly comparing a bit field to a Boolean type will yield unexpected results | Yes | Yes | |
| format string mismatch: character string passed as parameter <number> when wide character string is required in call to <function> | Yes | Yes | |
| format string mismatch: wide character string passed as parameter <number> when character string is required in call to <function> | Yes | Yes | |
| potential mismatch between sizeof and countof quantities | Yes | Yes | |
| incorrect call to <function>: consider using <function> which accepts a va_list as an argument | Yes | Yes | |
| 'realloc' may return null pointer: assigning a null pointer to <variable>, which is passed as an argument to 'realloc', will cause the original memory block to be leaked | Yes | Yes | |
| argument <number> is null: it does not adhere to function specification of <function> | Yes | Yes | |
| illegal constant in exception filter can cause unexpected behavior | Yes | Yes | |
| Possible infinite loop: use of the constant EXCEPTION_CONTINUE_EXECUTION in the exception-filter expression of a try-except | Yes | Yes | |
| Incorrect operator: Zero-valued flag cannot be tested with bitwise-and. Use an equality test to look for zero-valued flags | Yes | Yes | |
| Incorrect order of operations: bitwise-or has higher precedence than the conditional-expression operator. Add parentheses to clarify intent | Yes | Yes | |
| Incorrect order of operations: bitwise-and has higher precedence than bitwise-or. Add parentheses to clarify intent | Yes | Yes | |
| Incorrect operator: tested expression is constant and non-zero. Use bitwise-and to determine whether bits are set | Yes | Yes | |
| incorrect operator: logical-not (!) is not interchangeable with ones-complement (~) | Yes | Yes | |
| Ill-defined __try/__except: use of the constant EXCEPTION_CONTINUE_SEARCH or another constant that evaluates to zero in the exception-filter expression. The code in the exception handler block is not executed | Yes | Yes | |
| use of the comma-operator in a tested expression causes the left argument to be ignored when it has no side-effects | Yes | Yes | |
| exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This may mask exceptions that were not intended to be handled | Yes | Yes | |
| empty _except block | Yes | Yes | |
| warning 6323 - use of arithmetic operator on Boolean type(s) | Yes | Yes | |
| potential incorrect use of <function1>: Did you intend to use <function2>? | Yes | Yes | |
| potential comparison of a constant with another constant | Yes | Yes | |
| Potential buffer overrun: SysAllocStringLen copies <number> characters from the string <variable> without validating the number of characters to copy. The code may crash | Yes | Yes | |
| warning C6328:<type> passed as parameter <number> when <type> is required in call to <function> | Yes | Yes | |
| Invalid parameter: passing MEM_RELEASE and MEM_DECOMMIT in conjunction to <function> is not allowed. This results in the failure of this call | Yes | Yes | |
| Invalid parameter: passing zero as the dwFreeType parameter to <function> is not allowed. This results in the failure of this call | Yes | Yes | |
| Invalid parameter: passing MEM_RELEASE and a non-zero dwSize parameter to <function> is not allowed. This results in the failure of this call | Yes | Yes | |
| sizeof operator applied to an expression with an operator may yield unexpected results | Yes | Yes | |
| leaking process information handle <handlename> | Yes | Yes | |
| arithmetic operator has precedence over question operator, use parentheses to clarify intent | Yes | Yes | |
| Shutdown API <function> requires a valid dwReason or lpMessage | Yes | Yes | |
| buffer overrun due to conversion of an element count into a byte count: an element count is expected for parameter <number> in call to <function> | Yes | Yes | |
| dividing sizeof a pointer by another value | Yes | Yes | |
| invalid data: accessing <buffer name>, the readable size is <size1> bytes, but <size2> bytes may be read: Lines: x, y | Yes | Yes | |
| buffer overrun: accessing <buffer name>, the writable size is <size1> bytes, but <size2> bytes may be written: Lines: x, y | Yes | Yes | |
| <argument> may be <value>: this does not adhere to the specification for the function <function name>: Lines: x, y | Yes | Yes | |
| <argument> may not be <value>: this does not adhere to the specification for the function <function name>: Lines: x, y | Yes | Yes | |
| Using <function name> to perform a case-insensitive compare to constant string <string name>. Yields unexpected results in non-English locales | Yes | Yes | |
| Using <function name> in a default locale to perform a case-insensitive compare to constant string < string name>. Yields unexpected results in non-English locales | Yes | Yes | |
| invalid annotation: value for <name> property is invalid | Yes | Yes | |
| annotation conflict: <name> property conflicts with previously specified property | Yes | Yes | |
| annotation conflict: references may not be marked Null=Yes or Null=Maybe | Yes | Yes | |
| invalid annotation: property may only be used on values of pointer, pointer-to-member, or array type | Yes | Yes | |
| invalid annotation: MustCheck property may not be used on values of void type | Yes | Yes | |
| invalid annotation: <name> property may only be used on values of pointer or array types | Yes | Yes | |
| annotation conflict: Null property at Deref=0 on a post condition must be a subset of the Null property on the precondition | Yes | Yes | |
| invalid annotation: write access is not allowed on const values | Yes | Yes | |
| invalid annotation: 'return' cannot be referenced from a precondition | Yes | Yes | |
| invalid annotation: NullTerminated property may only be used on values of pointer or array type | Yes | Yes | |
| invalid annotation: MustCheck property must be Yes or No | Yes | Yes | |
| invalid annotation: Null property must be Maybe if the Valid property is No | Yes | Yes | |
| invalid annotation: ElementSizeConst requires additional size properties | Yes | Yes | |
| invalid annotation: value of the <name> property exceeds the size of the array | Yes | Yes | |
| warning C6515 - invalid annotation: <name> property may only be used on values of pointer type | Yes | Yes | |
| invalid annotation: no properties specified for <name> attribute | Yes | Yes | |
| annotation conflict: ValidElementsConst and ValidBytesConst may not be specified on the buffers that are not readable | Yes | Yes | |
| annotation conflict: WriteableElementsConst and WriteableBytesConst may not be specified on buffers that are not writable | Yes | Yes | |
| invalid size specification: * operator can only be applied to pointer types | Yes | Yes | |
| invalid size specification: expression must be of integral type | Yes | Yes | |
| invalid size specification: parameter <name> not found | Yes | Yes | |
| invalid size specification: property value may not be valid | Yes | Yes | |
| warning C6526 - invalid size specification: expression must be of array or pointer type | Yes | Yes | |
| warning 6530: unrecognized format string style <name> | Yes | Yes | |
| buffer cannot be of size <n>, bigger than max(size_t) | Yes | Yes |
This post summarizes the new functionality you will experience sing the Code Analysis functionality in Visual Studio 2010. Note that Code Analysis is only available in the Premium and Ultimate editions of Visual Studio 2010.
Rule Sets
In Visual Studio 2010 you can manage the list of rules that are executed against your managed code using rule sets. Rule sets are persisted as xml files that may be included as part of your project or solution and checked into source code control along with your code. Visual Studio ships with several pre-defined rule sets
- Basic Correctness
- Basic Design Guidelines
- Extended Correctness
- Extended Design Guidelines
- Globalization
- Minimum Recommended
- Security
The new rule set editor allows you to create your own custom rule sets. You access the rule set configuration dialog and rule set editor from the Project Properties \ Code Analysis tab. For more information on using rule sets see the MSDN documentation: http://msdn.microsoft.com/en-us/library/dd264949(VS.100).aspx.
You also have the ability to configure all projects in a solution to use the same rule set from the Solution Properties. See the MSDN documentation: http://msdn.microsoft.com/en-us/library/dd465181(VS.100).aspx.
New Rules
The following managed code analysis rules are new
| Validate arguments of public methods | |
| Do not pass literals as localized parameters | |
| Dispose objects before losing scope | |
| Review SQL queries for security vulnerabilities | |
| Security critical constants should be transparent | |
| Security critical types may not participate in type equivalence | |
| Default constructors must be at least as critical as base type default constructors | |
| Delegates must bind to methods with consistent transparency | |
| Methods must keep consistent transparency when overriding base methods | |
| Level 2 assemblies should not contain LinkDemands | |
| Members should not have conflicting transparency annotations | |
| Transparent methods must contain only verifiable IL | |
| Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attribute | |
| Transparent methods may not use the HandleProcessCorruptingExceptions attribute | |
| Transparent code must not reference security critical items | |
| Transparent code must not reference security critical items | |
| Transparent methods must not satisfy LinkDemands | |
| Transparent code should not be protected with LinkDemands | |
| Transparent methods should not use security demands | |
| Transparent code should not load assemblies from byte arrays | |
| Transparent methods should not be decorated with the SuppressUnmanagedCodeSecurityAttribute | |
| Types must be at least as critical as their base types and interfaces | |
| Transparent methods may not use security asserts | |
| Transparent methods must not call native code | |
| Do not dispose objects multiple times | |
| Literals should be spelled correctly | |
| Dispose methods should call base class dispose | |
| Provide correct arguments to formatting methods |
Rules CA1062, CA1303, CA2000, CA2100, CA2202, CA2204, CA2215 and CA2241 are all implemented using the new Phoenix analysis engine. We’ll discuss the Phoenix engine in a subsequent blog post.
Metrics
We improved the accuracy of calculating several metrics for switch statements and catch blocks.
New errors and warnings that FxCopCmd will generate
The follow new error codes may be generated when FxCopCmd is unable to successfully analyze your code for one reason or another.
| The rule 'RuleId' referenced in rule set 'RuleSetName' could not be found. | |
| The rule 'RuleId' could not be found. | |
| Failed to load rule set file or one of its dependent rule set files. | |
| No analysis was performed because the specified rule set did not contain any FxCop rules. | |
| Unsupported metadata construct: Type 'TypeName' contains both a property and a field with the same name 'PropertyFieldName' | |
| CA0066 | The value '{0}' provided to the /targetframeworkversion is not a recognized version. |
| Directory not found. | |
| Debug information could not be found for target assembly 'AssemblyName'. | |
| UsingAlternatePlatform. FrameworkVersion1 could not be found. Using FrameworkVersion2 instead. For best analysis results please ensure that the correct .NET Framework is installed. | |
| Unable to analyze permission attributes |
Support for C# 4 language constructs
Support for C++ 0x language constructs
What’s gone
- Policy Migration – TFS Checkin Policy
In Visual Studio 2008 you had the ability to copy your Code Analysis checkin policy settings from a TFS team project into the Solution / Project(s). This feature is not available in Visual Studio 2010. Use the new rule sets feature to configure the rules that will be executed during a build.
- The following rules are no longer available
| Do not initialize unnecessarily | ||
| Security transparent assemblies should not contain security critical code | Replaced by CA2136 | |
| Security transparent code should not assert | Replaced by CA2147 | |
| Security transparent code should not reference non-public security critical members | Replaced by CA2140 |
- Managed C++ in-source suppression. Use the code analysis global suppression file. If you need the suppression attributes to be defined in your source code you will need to copy or move them from the global suppression file into your source code.
Conclusion
Questions and comments are welcome. You may either post a comment for this blog or post a question on the Code Analysis team’s MSDN forum.
The Visual Studio Code Analysis Team.
Two weeks ago, I introduced you to Visual Studio 2010 September '08 CTP (Community Technology Preview). This CTP is available as a Virtual PC (VPC) image which can be downloaded at http://go.microsoft.com/fwlink/?LinkId=129231. The goal of the Community Technology Preview is to obtain feedback from our customers on the new scenarios we have enabled. If you haven't already downloaded the CTP, do it now and take it out for a spin.
There are many new cool features with the CTP such as an Historical Debugger and Impact Analysis of code changes, but today we are going to focus on Rule Sets for code analysis. (For an overview of all the neat stuff happening in code analysis, check out this PDC video http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/TL60.wmv ) Configuring code analysis in Visual Studio 2008 and earlier versions required evaluating each individual rule to determine whether it was important enough to turn on and fix for your project. This might be a very time-consuming process that made it difficult to make sure that the most important problems were identified and fixed. With rule sets, code analysis can now be configured much more quickly and easily with sets of rules that are targeted at specific scenarios or areas of emphasis. Let's take a look at how this works.
The following scenario comes from our CTP walkthrough. You can find the walkthrough and more details when you download the CTP as described above. Let's assume that you have the DinnerNow – Kiosk solution open and is the active project. On the Analyze menu, click Configure Code Analysis for DinnerNow.Restaurants.Kiosk. The property page for Code Analysis is displayed:
This screen tells us that Microsoft All Rules will be executed when we run code analysis, but what if we didn't want to run every Microsoft rule? What if we have a specific scenario we wish to target? We can change which rule set to run by clicking on Open which brings up:
We can select which rule set(s) by simply selecting or deselecting the appropriate box. Notice that each rule set has a brief description of the types of rules within the rule set. Further, you can open up each individual rule set and see the specific rules that make up the rules sets. You can also turn on or off individual rules within a rule set. Finally, you can adjust the type of action a rule will trigger. In the past, code analysis rules have been limited to build Warnings, but now you can elevate code analysis rules to build Errors.
As you can see, rules sets provide a powerful way to focus code analysis on the scenarios and rules that matter most to you. You can also create custom rule sets based on your specific needs. We wont go into it today, but if you download the CTP, the Walkthrough explains how to customize a rule set.
Give it a try and let us know what you think.
Cris
At this year's PDC, Microsoft released Visual Studio 2010 September '08 CTP (Community Technology Preview). This CTP is available as a Virtual PC (VPC) image which can be downloaded at http://go.microsoft.com/fwlink/?LinkId=129231. The goal of the Community Technology Preview is to obtain feedback from our customers on the new scenarios we have enabled. If you are interested in code analysis, you need to get this CTP and here is why.
The code analysis team is excited to share with you new code analysis features and rules in this CTP, including:
- Rule sets - code analysis can now be configured much more quickly and easily with sets of rules that are targeted at specific scenarios or areas of emphasis
- Enhanced policy support - enforce your rule set with the code analysis check-in policy
- 8 New Data Flow rules - find hard-to-detect flaws with these advanced dataflow rules for managed code; including certain SQL injection vulnerabilities
Included with the CTP is a walkthrough guide. Inside the walkthrough is a section dedicated to these exciting code analysis scenarios. Over the next couple of weeks we will continue to blog about rule sets, policy support, and data flow rules so be sure to come back after you get the CTP.
Now go get the CTP and starting sending us your feedback! http://go.microsoft.com/fwlink/?LinkId=129231
I've just published a post over my blog about a new feature we added for Visual Studio 2008 SP1 and FxCop 1.36.
New for Visual Studio 2008 SP1 and FxCop 1.36 – Multi-targeting rule
We are pleased to announce that we've released the next version of FxCop. This release has a number of changes since FxCop 1.36 Beta 2, including, but not limited to, the following:
-
Bug fixes that reduce noise, missing analysis and rule crashes.
-
New portability rule: Use Only API from Targeted Framework. This rule will fire when the target assembly taking a dependency on a new API only included in a later version or in a service pack.
-
New option for new portability rule for selecting target framework for analysis.
-
Set the target framework in the UI via Project -> Option -> Spelling & Analysis -> Target Framework
-
Set the target framework on the command-line via the /targetframeworkversion switch. e.g: /targetframeworkversion:v2.0, /targetframeworkversion:v3.0, or /targetframeworkversion:v3.5
Compared with FxCop 1.35, FxCop 1.36 Beta 2 had changes including, but not limited to, the following:
-
200+ bug fixes that reduce noise, missing analysis and rule crashes
-
New option for skipping analysis over tool generated code
-
Turn this on in the UI via Project -> Options -> Spelling & Analysis -> Suppress analysis results against generated code
-
Turn this on on the command-line via the /ignoregeneratedcode switch.
-
Better support for C++/CLI and the Compact Framework
-
Language 'friendly' API names in the UI and resolutions (ie Visual Basic syntax if running over a Visual Basic binary)
-
New globalization, design and usage rules
-
Performance improvements that cut analysis by 2x and use half as much memory
-
Documentation that is now available on MSDN
There are also some other underlying changes that we will talk about in some future posts.
Download it, and tell us what you think. If you have any feedback, bug reports or any questions, feel free to head over to the Code Analysis forum and ask away.
Note: If you already have FxCop 1.36 Beta 2 installed, please uninstall it first before you install FxCop 1.36. Otherwise, you may see an error when you install FxCop 1.36 on top of FxCop 1.36 Beta 2.
If you accidentally install FxCop 1.36 without uninstalling FxCop 1.36 Beta 2, please go to Add/Remove program to uninstall FxCop 1.36, and reinstall FxCop 1.36.
[EDIT] Note: FxCop 1.36 RTM shipped with additional tracing turned on. This can make the FxCop output harder to read. To turn tracing off, edit the FxCop.exe.config or FxCopCmd.exe.config files in the FxCop install directory. Find the line that contains <add name="Trace" value="2" /> and change the "2" to "0".
For those that are interested, I've just started a new personal blog, Dave's Box, where I will be talking about FxCop, Framework Design Guidelines, and the recently announced Managed Extensibility Framework.
I've just posted a couple of posts detailing changes we made to FxCop 1.36:
FxCop now ships with the spell checker libraries
Reference resolution changes in Code Analysis and FxCop
You can subscribe via the one of the two following links:
Subscribe via reader
Subscribe via email
We've just uploaded FxCop 1.35 to MSDN Code Gallery after we lost our home on GotDotNet - this is for those teams that either do not want to or just aren't ready to upgrade to FxCop 1.36 Beta.
For those that are already using FxCop 1.35, you'll probably notice that we flicked the switch to cause it to prompt you to download FxCop 1.36. We've love you to download it and try it out (it can be installed side-by-side without any issues with FxCop 1.35). If you hit any bugs, issues or just have some feedback about the new or existing versions of FxCop, feel free to head over to the Code Analysis forum and post away.
I've upgraded from FxCop 1.35 to 1.36 and now FxCop has started to fire warnings against typed DataSets and other generated code. How do I turn this off?
The reason this is occurring is because we changed the way that FxCop analyzed generated code. Whereas previously in 1.35, FxCop would only ignore particular generated code (such as DataSets), FxCop 1.36 will now either ignore no generated code, or all generated code. The former is the default.
To change this behavior and have FxCop skip over generated code:
Using an FxCop project:
- Open your FxCop project in FxCop
- Choose Project -> Options -> Spelling & Analysis
- Check Suppress analysis results against generated code
- Click OK
Via the command-line:
- Pass the /ignoregeneratedcode switch, for example:
FxCopCmd.exe /file:MyAssembly.dll /out:AnalysisResults.xml /ignoregeneratedcode
For more information on FxCop's behavior over generated code, see Correct usage of the CompilerGeneratedAttribute and the GeneratedCodeAttribute.
Update: You can now download FxCop 1.35 directly from MSDN Code Gallery.
As you many you have well noticed, GotDotNet was officially retired last month now that the last of its functionality was superceded by MSDN Code Gallery. Unfortunately, at the same time, the FxCop team page, the download for FxCop 1.35 and the rule documentation was also removed.
We were told last year about the deprecation of GotDotNet and we had hoped that by now we would have had a new team site on MSDN, however, a variety of factors, some within our control and some beyond our control, prevented that from happening in time.
In the meantime, while we sort out new home for our beloved FxCop, here are a couple of workarounds:
To download FxCop
- Upgrade to FxCop 1.36 Beta. This is one of our most stable beta's to-date; which is not surprising considering that some of the same bits also shipped in Visual Studio 2008. Go ahead, download FxCop 1.36 today - you won't be disappointed.
- Download the Windows SDK. The Windows SDK includes the FxCop 1.35 setup. You might already have it installed if you have Visual Studio 2008, otherwise, download it. Either way, once installed, FxCop 1.35 setup can be found via Start -> All Programs -> Microsoft Windows SDK [Version] -> Tools -> Install Microsoft FxCop.
To view the documentation
- MSDN Library. Both the FxCop documentation and rule documentation are available on the MSDN Library.
- Installed Help. FxCop 1.35 comes with a CHM (pronounced 'chum') containing FxCop and rule documentation. Albeit a little out-of-date when compared to the online version, access it via Start -> All Programs -> Microsoft FxCop 1.35 -> FxCop Documentation or via Help -> Using Microsoft FxCop inside FxCop.
Jason Kresowaty has posted a great tutorial on writing Code Analysis/FxCop rules. He also spends time on explaining parts of the Introspection API, including the different nodes and their relationship to each other.
It's a great read, even if you've written some Code Analysis rules before. Definitely recommended.
![]() |
Krzysztof and Brad have announced they are working on the second edition of the awesome Framework Design Guidelines and are looking for feedback on what they should put in it. For those that don't know, a lot of our Code Analysis rules are based on the writings in this great book, so expect to see additional rules in the future based on the new guidelines in the second edition. To provide feedback, head over to Krzysztof's blog and post a comment. |
In response to a lot of recent requests, we've put together a complete list of rules that shipped in the different versions of Visual Studio Code Analysis and FxCop. Attached is an Excel worksheet providing this information for Visual Studio 2005, Visual Studio 2008, FxCop 1.35 and FxCop 1.36 Beta.
One of things you'll notice as you read through the list is that we removed some rules from the later versions. There are a few reasons for this:
- Noise and applicability. We use feedback from customers, SQM data (to see which rules users turn off), and input from internal teams (Windows, Office, CLR, etc) to determine the rules that are noisy without adding any perceivable value. There are also rules that are either no longer applicable or can no longer fire. for example, a rule could have been firing on a limitation of the CLR which has since been fixed in later versions.
- Merged rules. Sometimes it makes sense to merge rules that fire on similar things, for example, the analysis in SecureGetObjectDataOverrides was already covered by OverrideLinkDemandsShouldBeIdenticalToBase, so these two rules were merged. Similarly, LongAcronymsShouldBePascalCased, ShortAcronymsShouldBeUppercase and IdentifiersShouldBeCasedCorrectly all fired on the casing of identifiers, and hence were merged in the later.
- Analysis engine removed. In Visual Studio 2008 and FxCop 1.36 we removed one of our analysis engines. This engine was removed for a variety of reasons; it increased analysis time (although the engine encompassed less than 5% our analysis, it took up 50% of our time-to-analyze), indeterministic results (results appearing and disappearing between runs), and bugs found within the engine (and hence the rules that depended on it) required huge architectural changes. We instead decided to invest the resources that we would have spent on fixing the old engine, on a new data flow analysis engine based on Phoenix, which we will ship in a future version of Visual Studio.
There are also more differences between Visual Studio Code Analysis and FxCop than just the rules - in a future blog post I will cover these in detail.
Code analysis defect counts are available in the cube that is part of the TFS Data Warehouse. This post shows you how to hook up Excel to show code analysis counts in a pivot table.
First off you need to connect Excel up to the data warehouse that has the data. Under the Data tab in Excel select From Other Sources, From Analysis Services.
Then you need to give the name of the server with the data warehouse. In the standalone TFS case this will be whatever machine is running TFS. Assuming you have read permissions with your Windows account you can click Next, otherwise enter a user name and password that has access to the server and click Next.
Then, select the database (usually TfsWarehouse) and select the Build table.
Click Next and then supply whatever additional information that will help you remember this data connection.
Click Finish. Then define how you want to show the data in Excel - e.g. a pivot table.
Click OK which gives you the following:
In the PivotTable Field List, Expand Build Project where you will find two fields: Static Analysis Errors and Static Analysis Warnings:
You can click the checkboxes to add these to the values for your table. In most cases Static Analysis Warnings would be the most useful since Static Analysis Errors would typically stop the build.
To complete the picture you can play with the pivot table and pivot and filter as you see fit. As a simple example you can add the Build field:
Which will give you one row per build in the pivot table.
Of course this data can be combined with other build data and charted etc. according to your needs. We are considering what reporting to provide in future versions so would love to hear your feedback on this feature and what you would like to see.
Join members of the Visual Studio Team System product group to discuss features available in Team Foundation Server, Team Suite, Architecture Edition, Development Edition, Database Edition, and Test Edition. In addition, discuss what's new for these editions for Visual Studio 2008.
We will be holding two sessions:
Join the chat on Wednesday, December 5th, 2007 from 10:00am - 11:00am Pacific Time. Add to Calendar | Additional Time Zones
-and-
Join the chat on Wednesday, December 5th, 2007 from 4:00pm - 5:00pm Pacific Time. Add to Calendar | Additional Time Zones









