tags:

views:

315

answers:

2

I'm upgrading a solution from .NET 2.0 to 3.5. One of the projects is a code-generator app that is compiled and then executed via a post-build event. When it is run, it generates some code and invokes csc.exe to compile the generated code. The way it determines which csc.exe to invoke is using System.Environment.Version property (which returns the runtime version, rather than the framework version). So it always ends up running v2.0 of csc.exe, rather than v3.5 that I expect.

So the question is how do I detect that the current VS project is targeting v3.5 of the framework?

A: 

If you have the *.proj file, you can load it to XmlDocument and XPath the target framework: /Project/PropertyGroup/TargetFrameworkVersion/text()

Grzenio
A: 

Team Foundation website has a recipe for restricting the Target Framework Version (and thus targeting).

You will need at least the v1.2.0.306 MSBuild Community Tasks installed/available.

Source

===Description===
This recipe checks the <TargetFrameworkVersion> of a Visual Studio 2008 project file. It fails the build if the version does not match the allowed version.

This is useful if your destination environment is .NET 2.0 only and you want to prevent people from building solutions that target .NET 3.0 and 3.5.

===Usage===
Add to TFSBuild.proj

===Source===
[http://ozgrant.com/2007/10/22/tfs2008-restrict-target-framework-version-task/|Grant Holliday - TFS2008: Restrict Target Framework Version Task]


====Script====
@@
    <!-- TFS Build 2008.
         This snippet checks the <TargetFrameworkVersion> of a Visual Studio 2008 project file.
         It fails the build if the version does not match the allowed version.

         This should be used when you want to use VS2008, but ensure that your binaries remain as .NET 2.0
    -->

      <PropertyGroup>
        <!-- The TargetFrameworkVersion that you want to match. e.g. v2.0, v3.0 or v3.5 -->
        <AllowedTargetFrameworkVersion>v2.0</AllowedTargetFrameworkVersion>
      </PropertyGroup>


      <!-- Override the Team Build AfterGet target, before any compilation starts -->
      <Target Name="AfterGet" >
        <CallTarget Targets="CheckTargetFrameworkVersions" />
      </Target>

      <UsingTask AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.Xml.XmlQuery" />

      <!-- Only run if the AllowedTragetFrameworkVersion property is set -->
      <Target Name="CheckTargetFrameworkVersions" Condition=" '$(AllowedTargetFrameworkVersion)' != '' ">
        <Message Text="Allowed Target Framework Version is: $(AllowedTargetFrameworkVersion)" Importance="high" />

        <!-- Get all *.csproj files in the working directory.
        Ideally this should look at the current build configuration
        and return the filenames of the projects to be built.
        But as Team Build passes SolutionToBuild to MSBuild, we can't get
        the list of projects easily.
        -->
        <CreateItem Include="$(SolutionRoot)\**\*.csproj">
          <Output TaskParameter="Include" ItemName="ProjectFiles" />
        </CreateItem>

        <!-- Extract the TargetFrameworkVersion element from each of the project files -->
        <Xml.XmlQuery
          NamespaceDefinitions="n=http://schemas.microsoft.com/developer/msbuild/2003"
          XmlFileName="%(ProjectFiles.FullPath)"
          XPath="/n:Project/n:PropertyGroup/n:TargetFrameworkVersion">
          <Output TaskParameter="Values" ItemName="TargetFrameworkVersions" />
        </Xml.XmlQuery>

        <Message Text="Found Target Framework Version: %(TargetFrameworkVersions._value)" Importance="low" />

        <!-- Throw an error if any of the target versions don't match -->
        <Error Condition="'%(TargetFrameworkVersions._value)' != '$(AllowedTargetFrameworkVersion)'"
               Text="Target Framework Version is not allowed: %(TargetFrameworkVersions._value). Allowed version: $(AllowedTargetFrameworkVersion)" />

      </Target>
@@

===Notes===
* The build will fail if any of the projects within the build don’t match the <AllowedTargetFrameworkVersion> that has been set.
* You will need at least the v1.2.0.306 [MSBuild Community Tasks] installed/available.
* Currently it matches all *.csproj files recursively, regardless of whether they are in the build configuration or not.
* If you want to actually enforce this, make sure that developers can’t change the file. It might be useful to store it on the server and use an <Include>.
0A0D