21

How can i get the version of the .NET Framework i am targeting, rather than the version of the .NET framework the app is currently running under?

For example, if the application targets .NET Framework 4.5, i would need to know that i am targeting .NET Framework 4.5.

For example, checking System.Environment.Version:

  • when targeting .NET Framework 4: 4.0.30319.18502
  • when targeting .NET Framework 4.5: 4.0.30319.18502

So that doesn't work.

The real goal is to try to work around the lack of compiler defines in .NET.

Community
  • 1
  • 1
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • 5
    This question doesn't really make much sense. If your program is compiled using .NET Framework 4.5, but you never use `dynamic`, `async`, or any of the other .NET Framework 4.5 specific features, in theory you could run it on .NET Framework 3.5 without modification. But why does it matter? Are you trying to write a program utilizing `dynamic`, but be able to compile it to an alternate 3.5 version that *doesn't* use `dynamic`? Perhaps in a reduced functionality mode? – Robert Harvey Sep 30 '13 at 14:36
  • Does this help? http://stackoverflow.com/questions/8517159/how-to-detect-at-runtime-that-net-version-4-5-currently-running-your-code/8543850#8543850 – Matthew Watson Sep 30 '13 at 14:38
  • @MatthewWatson: That's at runtime, not compile time. – Robert Harvey Sep 30 '13 at 14:40
  • 4
    Does this help? http://stackoverflow.com/questions/3436526/detect-target-framework-version-at-compile-time – Tim S. Sep 30 '13 at 14:46
  • @TimS. That question *"Detect target framework version at compile time"* is exactly what i want! Unfortunately there's no solution (aside from requiring the person using the shared code to alter their solution). – Ian Boyd Sep 30 '13 at 14:56
  • @IanBoyd thats all you can do. – Daniel A. White Sep 30 '13 at 15:11
  • @DanielA.White Fortunately it can be done; see the accepted answer. Don't forget: don't confuse the *question* with the *example*. – Ian Boyd Sep 30 '13 at 15:14
  • Why are you trying to share code instead of a compiled assembly? Then you just target whatever framework version you want, and people who want to use your assembly must target at least that version. (the downside is that you cannot use better, newer alternatives in most cases) – Tim S. Sep 30 '13 at 15:16

2 Answers2

36

That's simple - check the TargetFrameworkAttribute:

var targetFrameworkAttribute = Assembly.GetExecutingAssembly()
    .GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false)
    .SingleOrDefault();
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • 1
    That only works at runtime, not at compile time. Refer to the last sentence in the OP, where he states that he's looking for compiler defines. – Robert Harvey Sep 30 '13 at 14:44
  • 1
    @RobertHarvey So what? OP can solve this using a simple if else statements. and I don't see anywhere mentioned *it should be compile time* If it needs to be compile time then as Tim suggested Conditional compilation arguments would help – Sriram Sakthivel Sep 30 '13 at 14:49
  • Oh i get what the code is doing now. At first i thought it was using 4.5 specific code. Now i realize it's actually asking the assembly what it was targeted for. And while this won't help me solve my problem in any performance-critial way, it absolutely answers my question. (Knowing that it is .NET 4.5, i can use reflection to call a the method i need. Yes reflection is a few orders of magnitude slower, but at least it will work). – Ian Boyd Sep 30 '13 at 15:01
  • Hmmm, I think this class is new in .net 4.0, So i don't think you can use it before .net 4.0 :( – Sriram Sakthivel Sep 30 '13 at 15:05
  • It's fortunate that the only two projects that i'm dealing with right now are 4. And one i can update to 4.5. But that means i can't just check-in the code changes as is; as some people target .NET 2 or 3/3.5 – Ian Boyd Sep 30 '13 at 15:12
5

What prevents you from using an ordinary /define?

csc /define:NET45 /optimize /out:MyProgram.exe *.cs

with

using System;
public class Test 
{
    public static void Main() 
    {
        #if (NET45) 
            Console.WriteLine("NET45 targeted");
        #else
            Console.WriteLine("NET45 not targeted");
        #endif
    }
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Because i don't have access to the project. This is in shared code that could be run in a project that targets .NET 2, .NET 3, .NET 3.5, .NET 4, .NET 4.5, .NET 1, .NET *n+1* – Ian Boyd Sep 30 '13 at 14:54
  • this can easily be modified with checking `TargetFrameworkVersion`. – Daniel A. White Sep 30 '13 at 14:54
  • @IanBoyd you could conditionally include your references. – Daniel A. White Sep 30 '13 at 14:54
  • @IanBoyd: Just have whoever is compiling the code compile it using the appropriate `/define` on the csc command line. – Robert Harvey Sep 30 '13 at 14:55
  • @DanielA.White Is this *`TargetFrameworkVersion`* exposed anywhere at runtime? i mean: i **is**, because Windows is able to figure out which edition of the .NET Framework i want. – Ian Boyd Sep 30 '13 at 14:59
  • 2
    @IanBoyd Maybe you should explain what is your current use case (I mean, who owns/compiles the code, why you need to get the framework version...etc) cause right now it's not that clear if you're looking for a compile-time or run-time solution. – ken2k Sep 30 '13 at 14:59
  • @ken2k i am writing shared code. That code will be used in projects and solutions that i do not own, control, edit, manage, or create conditional defines for. There was a glaring omission in .NET framework that required me to write horribly fragile code as a workaround. .NET 4.5 finally added the missing functionality. But if someone were to compile the code while targeting .NET 2 the code file will not compile. i need a way to remove the *"new"* code from being compiled when not available. (Or you could read the linked question) – Ian Boyd Sep 30 '13 at 15:05
  • @IanBoyd no its an msbuild property. im really confused. you want it at runtime, but you don't. – Daniel A. White Sep 30 '13 at 15:09