Лучший способ определить, установлен ли .NET 3.5

Мне нужно программно определить, установлен ли .NET 3.5. Я думал, что это будет легко:

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

Что возвращает "2.0.50727.1434", поэтому нет такой удачи...

В моем исследовании у меня есть некоторые довольно неясные разделы реестра, на которые я могу смотреть, но я не уверен, что это маршрут. У кого-нибудь есть предложения?

Ответы

Ответ 1

Вы можете попробовать:

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

@Ник: Хороший вопрос, я попробую это немного.

Кев

Ответ 2

Это потому, что технически .NET 3.5 является расширением среды 2.0. Самый быстрый способ - включить сборку из .NET 3.5 и посмотреть, не сломается ли она.

System.Web.Extensions

Хорошая сборка, которая включена только в версию 3.5. Также кажется, что вы используете ASP.NET для запуска этой проверки, это действительно ограничивает вас, потому что вы не сможете проверить файловую систему или реестр, запущенные в защищенном режиме ASP.NET. Или вы всегда можете попытаться загрузить сборку из GAC, которая должна быть только в .NET 3.5, однако вы снова можете столкнуться с проблемами с разрешениями.

Это может быть один из тех случаев, когда вы спрашиваете себя: "Что я пытаюсь выполнить?" и посмотрите, есть ли альтернативные маршруты.

Ответ 4

@Kev, действительно нравится ваше решение. Спасибо за помощь.

Используя реестр, код будет выглядеть примерно так:

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

Мне было бы интересно, если любой из них будет работать в среде среднего доверия (хотя я работаю в полном доверии, поэтому не имеет значения, к чему я сейчас работаю).

Ответ 5

@komradekatz, ваше решение ниже из MSDN для удобства других, изучающих это. Мне не нравится это решение, потому что он использует агент пользователя для определения версии. Это нежизнеспособно для того, что мне нужно (я пишу библиотеку классов, которая должна знать, установлен ли .NET 3.5). Я также сомневаюсь, насколько надежным может оказаться это решение.

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

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

<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 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>

На моей машине эти выходы:

Этот аппарат имеет правильную версию .NET Framework 3.5.

Эта строка userAgent машины: Mozilla/4.0 (совместимо; 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;.СЕТЬ CLR 3.5.21022; Zune 2.5).

Ответ 6

Еще одна интересная находка - наличие сборок здесь:

C:\Program Files\Reference Сборки \Microsoft\Framework\v3.5

Вы бы подумали, что Microsoft построит чек для "последней версии" в рамках.

Ответ 7

Если вы хотите, чтобы определенная версия .net была установлена ​​и могла управлять распределением вашего приложения, вы действительно должны использовать ClickOnce. Он позволяет указать минимальную требуемую версию инфраструктуры .Net, которая должна быть установлена, и она будет проверять только при ее установке, чтобы все последующие стартапы не мешали ненужной проверкой.

Кроме того, с помощью ClickOnce вы получаете бесплатное обновление. Почему кто-то не хочет его использовать?

Чтобы настроить приложение ClickOnce, просто щелкните правой кнопкой мыши проект в Visual Studio и перейдите к настройкам публикации. Это создаст специальную сборку вашего приложения, которую вы можете разместить на своем веб-сайте. Когда пользователи загружают программу, установщик проверяет наличие каких-либо предварительных условий, таких как .Net для вас.

Ответ 8

Один из вариантов - обнаружить 4.0, используя строку версии:

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

то, поскольку 2.0 и 2.5 используют номер версии CLR, их необходимо устранить, проверив реестр. Поскольку эти версии уже выпущены, строки, которые нужно искать, известны.

Ответ 9

Без каких-либо сбоев по загрузке и улавливанию исключений (что происходит медленно) проверьте изменения API класса между 2.0 и 3.5. Моноклассный статус очень полезен для этого. Например, вы можете проверить GC.Collect Method (Int32, GCCollectionMode), который находится в mscorlib, и был добавлен в 3.5.