views:

4443

answers:

15

I need to programatically determine whether .NET 3.5 is installed. I thought it would be easy:

<% Response.Write(Environment.Version.ToString()); %>

Which returns "2.0.50727.1434" so no such luck...

In my research I have that there are some rather obscure registry keys I can look at but I'm not sure if that is the route to go. Does anyone have any suggestions?

A: 

http://msdn.microsoft.com/en-us/library/bb909885.aspx

That deals with the client machine.

Eugene Katz
+2  A: 

That is because technically .NET 3.5 is an extension of the 2.0 framework. The quickest way is to include an assembly from .NET 3.5 and see if it breaks.

System.Web.Extensions

Is a good assembly that is only included in version 3.5. Also it seems that you are using ASP.NET to run this check, this really limits you because you will be unable to check the file system or the registry running in the protected mode of ASP.NET. Or you can always problematically try loading an assembly from the GAC that should only be in .NET 3.5, however you may run in to problems with permissions again.

This may be one of those times where you ask your self "What am I trying to accomplish?" and see if there are alternative routes.

Nick Berardi
isn't System.Web.Extensions part of ASP.NET AJAX already, with version number 1.0.something?
Michael Stum
@Michael, yes. It's 1.0.61231.0
AndyMcKenna
A: 

@komradekatz

That is to determine if the browser has .NET 3.5 installed not if the server has .NET 3.5 installed.

Nick Berardi
A: 

@komradekatz, your solution below from MSDN for convenience for others looking into this. I do not like this solution because it uses the user agent to determine the version. This is not viable for what I need (I am writing a class library that needs to know whether .NET 3.5 is installed). I also question how reliable this solution may prove to be.

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<HTML>
  <HEAD>
    <TITLE>Test for the .NET Framework 3.5</TITLE>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8" />
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    var dotNETRuntimeVersion = "3.5.0.0";

    function window::onload()
    {
      if (HasRuntimeVersion(dotNETRuntimeVersion))
      {
        result.innerText = 
          "This machine has the correct version of the .NET Framework 3.5."
      } 
      else
      {
        result.innerText = 
          "This machine does not have the correct version of the .NET Framework 3.5." +
          " The required version is v" + dotNETRuntimeVersion + ".";
      }
      result.innerText += "\n\nThis machine's userAgent string is: " + 
        navigator.userAgent + ".";
    }

    //
    // Retrieve the version from the user agent string and 
    // compare with the specified version.
    //
    function HasRuntimeVersion(versionToCheck)
    {
      var userAgentString = 
        navigator.userAgent.match(/.NET CLR [0-9.]+/g);

      if (userAgentString != null)
      {
        var i;

        for (i = 0; i < userAgentString.length; ++i)
        {
          if (CompareVersions(GetVersion(versionToCheck), 
            GetVersion(userAgentString[i])) <= 0)
            return true;
        }
      }

      return false;
    }

    //
    // Extract the numeric part of the version string.
    //
    function GetVersion(versionString)
    {
      var numericString = 
        versionString.match(/([0-9]+)\.([0-9]+)\.([0-9]+)/i);
      return numericString.slice(1);
    }

    //
    // Compare the 2 version strings by converting them to numeric format.
    //
    function CompareVersions(version1, version2)
    {
      for (i = 0; i < version1.length; ++i)
      {
        var number1 = new Number(version1[i]);
        var number2 = new Number(version2[i]);

        if (number1 < number2)
          return -1;

        if (number1 > number2)
          return 1;
      }

      return 0;
    }

    -->
    </SCRIPT>
  </HEAD>

  <BODY>
    <div id="result" />
  </BODY>
</HTML>

On my machine this outputs:

This machine has the correct version of the .NET Framework 3.5.

This machine's userAgent string is: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; InfoPath.2; .NET CLR 1.1.4322; .NET CLR 3.5.21022; Zune 2.5).

sestocker
A: 

As Nick said, "This may be one of those times where you ask your self "What am I trying to accomplish?" and see if there are alternative routes."

What exactly are you trying to do? Why do you need to know if .Net 3.5 is installed? Maybe there is another way to do what you want without knowing the version.

Geoff
A: 

You could try:

static bool HasNet35()
{
    try
    {
     AppDomain.CurrentDomain.Load(
      "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
     return true;
    }
    catch
    {
     return false;
    }
}

@Nick: Good question, I'll try it in a bit.

Kev

Kev
Let's say that next week Microsoft releases version 4.0 and it does everything that 3.5 did, plus a little more. Would this still work? It seems like it relies on 3.5 being installed, but will break on a machine where a newer version is installed without installing 3.5.
Jared
@Jared - I agree completely. Framework version detection seems quite messy.
Kev
@Jared - and hence it just being a suggestion rather than a definitive answer.
Kev
I used to check for a specific assembly at the start of the program execution, but that only caused problems. First, if the user doesn't even have .net installed, they won't be able to start your application in the first place. Second, if they don't have the version that you would require, then you are forced to write your own code to either download it or redirect them somewhere to download it.This check caused crashes on specific machines, and I have since released a new version of software that removed this check. See my response below for a better solution.
Jared
+1  A: 

@Kev

Does that work in Medium Trust?

Nick Berardi
+1  A: 

@Kev, really like your solution. Thanks for the help.

Using the registry the code would look something like this:

RegistryKey key = Registry
        .LocalMachine
        .OpenSubKey("Software\\Microsoft\\NET Framework Setup\\NDP\\v3.5");
return (key != null);

I would be curious if either of these would work in a medium trust environment (although I am working in full trust so it doesn't matter to what I am currently working on).

sestocker
A: 

Another interesting find is the presence of assemblies here:

C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5

You'd think Microsoft would build a check for "latest version" into the framework.

sestocker
A: 

You should be able to use this class as well:

http://www.codeproject.com/KB/cs/frameworkversiondetection.aspx

Scott Dorman
A: 

Without any assembly loading and catching exceptions (which is slow), check for class API changes between 2.0 and 3.5. Mono Class Status is very helpful for this. For example you could check for GC.Collect Method (Int32, GCCollectionMode) which is in mscorlib and was added in 3.5 .

skolima
A: 

If you want to require a specific version of .net to be installed and can control the distribution of your application, you should really use ClickOnce. It allows you to specify the minimum required version of the .Net framework that should be installed, and it will only check when it is being installed so that all your subsequent startups are not impeded by an unnecessary check.

Also, with ClickOnce you get updating for free. Why wouldn't somebody want to use it?

To set up a ClickOnce application, just right click on the project within Visual Studio and go to the Publish Settings. This will create a special build of your application that you can place on your website. When users download the program, the installer will check for any prerequisites like .Net for you.

Jared
All very well but doesn't actually answer the OP's question. There are scenarios (which clearly the OP has encountered for himself) where you need to programmatically determine the framework version installed.
Kev
@Kev, you are right. Taking another look at the question I see that he is looking to check *if* it is installed and not *require* it to be installed. I'll leave my answer here in the hopes that anybody who misreads the OP may find the answer that they were looking for.
Jared
+2  A: 

True way (for ASP.NET) - link text

dmach
A: 

One option is to detect 4.0 using the version string:

    Environment.Version.CompareTo(new Version(4, 0));

then since 2.0 and 2.5 share a CLR version number, these need to be distenguished by checking the registry. Since those versions are released already, the strings to look for are known.

Phil