New for Visual Studio 2008 SP1 and FxCop 1.36 – Multi-targeting rule
Back in October of last year, Krzysztof Cwalina talked about the multi-targeting changes in Visual Studio 2008 and .NET 3.5. He mentioned the limitations in its design that could cause an application that explicitly targets .NET Framework 2.0 and .NET Framework 3.0 to accidently take a dependency on a new member or type that did not exist in the RTM version of that framework. As a workaround, he posted the source code of a Code Analysis/FxCop rule that could detect and fire on a member that took one of these dependencies.
A little while before he wrote that post, my team at the time, the Code Analysis team, was approached to see if we could ship a similar rule out of the box. Unfortunately, we ran out of time to get it included in Visual Studio 2008 RTM and FxCop Beta 2, however, I’m pleased to announce that we’ve added the rule, Use only API from targeted framework, to Visual Studio 2008 SP1 and FxCop 1.36 RTM release.
Note: The Visual Studio integration for this rule is only available in editions that support Code Analysis; Visual Studio Team Development Edition and Visual Studio Team Suite.
How this rule works
In Visual Studio, this rule reads the current targeted framework stored in the C# or Visual Basic project and fires on any usage of API that was not included in the RTM version of that framework. Whereas, in FxCop, the rule reads the targeted framework stored within the FxCop project or passed via the command-line.
The following table attempts to explain this:
|
|
When Target Framework (in Project properties or in FxCop project options/command-line) is set to:
|
|
Code Analysis/FxCop fires on usage of:
|
.NET Framework 2.0
|
.NET Framework 3.0
|
.NET Framework 3.5‡
|
|
.NET Framework 2.0
|
|
|
|
|
.NET Framework 2.0 SP1
|
•
|
•
|
|
|
.NET Framework 2.0 SP2
|
•
|
•
|
|
|
.NET Framework 3.0
|
•†
|
|
|
|
.NET Framework 3.0 SP1
|
•†
|
•
|
|
|
.NET Framework 3.0 SP2
|
•†
|
•
|
|
|
.NET Framework 3.5
|
•†
|
•†
|
|
|
.NET Framework 3.5 SP1
|
•†
|
•†
|
•
|
† MSBuild prevents a user from mixing these combinations in Visual Studio, so only FxCop can fire on this.
‡ Client-only Framework subset is not supported.
For example, when a user selects .NET Framework 3.0 as their project’s target framework, Code Analysis and FxCop will fire on any usage of members and types that were introduced in .NET Framework 2.0 SP1 and SP2, .NET Framework 3.0 SP1 and SP2, .NET Framework 3.5 and .NET Framework 3.5 SP1. This is because on a fresh install of .NET Framework 3.0 (such as on Vista RTM), none of these service packs or frameworks are installed.
Enabling in Visual Studio
By default, Visual Studio projects with the default Code Analysis settings will already have the rule enabled. To check this, do the following:
- In Solution Explorer, right-click on your project and choose Properties
- Choose the Code Analysis tab
- Expand the Portability node and ensure that Use only API from targeted framework is checked
Once this rule has been enabled, you need to make sure that you targeting the framework that you plan to release your application on. To verify this, do the following:
For C# projects:
- In Solution Explorer, right-click on your project and choose Properties
- Choose the Application tab
- From the Targeted Framework drop down, choose the framework that your application is targeting
For Visual Basic projects:
- In Solution Explorer, right-click on your project and choose Properties
- Choose the Build tab and click Advanced Compile Options…
- From the Target framework (all configurations) drop down, choose the framework that your application is targeting
Once you’ve done the above, running Code Analysis (Analyze -> Run Code Analysis) should now fire on any service pack dependencies your project has taken on. For example, using DateTimeOffset in a project that is set to target .NET Framework 2.0, will cause the following warning to output.
Enabling in FxCop
In contrast to Visual Studio, Use only API from targeted framework does not fire by default in FxCop. This is because FxCop does not have access to the project (.csproj, .vbproj) of the assembly that it is analyzing, and hence cannot automatically determine the Framework your application is targeting. Because of this, you need explicitly specify it; either via the FxCop project or via the command-line.
Enabling using an FxCop project
By default, FxCop projects will already have the rule enabled. To check this, do the following:
- Open your FxCop project in FxCop
- Choose the Rules tab
- Expand the Portability node and ensure that Use only API from targeted framework is checked
Once this rule has been enabled, it will not fire until you tell FxCop the framework you are targeting. To do this, do the following:
- Open your FxCop project in FxCop
- Choose Project -> Options and then choose the Spelling & Analysis tab
- From the Target Framework drop down, choose the framework you are targeting. Typically this would match the value specified in your C#, Visual Basic or C++ project’s properties.
- Click OK
Note: You can make this the default for all new FxCop projects and for the command-line by clicking Defaults… after you open the Project Options dialog and then following the rest of the steps above.
Once you’ve done the above, running analysis (Project -> Analyze) should now fire on any service pack dependencies your application has taken on. For example, using DateTimeOffset in a assembly that is set to target .NET Framework 2.0, will cause the following error to output:
Enabling via the command-line
While the preferred method to specify the target framework is by using an FxCop project as described above, you can also specify it explicitly via the command-line. The new /targetframeworkversion switch was added for this purpose. Its valid values are described below:
|
Argument
|
Description
|
|
/targetframeworkversion:2.0
|
Specifies .NET Framework 2.0
|
|
/targetframeworkversion:3.0
|
Specifies .NET Framework 3.0
|
|
/targetframeworkversion:3.5
|
Specifies .NET Framework 3.5
|
|
/targetframeworkversion:none
|
Disables the rule.
This is the default. However, it can useful to specify this argument if you want to override the associated setting stored in an FxCop project that is passed on the same command-line.
|
Specifying any of these arguments on a command-line will override the target framework setting stored in the FxCop project.
An example command-line would be the following:
FxCopCmd.exe /file:MyAssembly.dll /console /targetframeworkversion:2.0
Disabling the rule or targeting specific service packs
Use only API from targeted framework does not have support for targeting specific service packs, such as .NET Framework 2.0 SP1. If you want to deliberately take a dependency on a service pack, simply disable the rule by unchecking instead of checking the rule in the Enabling in Visual Studio and Enabling in FxCop sections.