Мне нужно программно определить, установлен ли .NET 3.5. Думал, будет легко:
<% Response.Write(Environment.Version.ToString()); %>
Что возвращает "2.0.50727.1434", так что не повезло ...
В своем исследовании я обнаружил, что есть несколько неясных ключей реестра, на которые я могу взглянуть, но я не уверен, стоит ли это делать. У кого-нибудь есть предложения?





Это потому, что технически .NET 3.5 является расширением платформы 2.0. Самый быстрый способ - включить сборку из .NET 3.5 и посмотреть, не сломается ли она.
System.Web.Extensions
Хорошая сборка, которая входит только в версию 3.5. Также кажется, что вы используете ASP.NET для запуска этой проверки, это действительно ограничивает вас, потому что вы не сможете проверить файловую систему или реестр, работающие в защищенном режиме ASP.NET. Или вы всегда можете попробовать загрузить сборку из GAC, которая должна быть только в .NET 3.5, однако вы можете снова столкнуться с проблемами с разрешениями.
Это может быть один из тех случаев, когда вы спрашиваете себя: «Чего я пытаюсь достичь?» и посмотрите, есть ли альтернативные маршруты.
@ Майкл, да. Это 1.0.61231.0
@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'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>
На моей машине это выводит:
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).
Вы можете попробовать:
static bool HasNet35()
{
try
{
AppDomain.CurrentDomain.Load(
"System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
return true;
}
catch
{
return false;
}
}
@ Ник: Хороший вопрос, попробую немного.
Кев
Допустим, на следующей неделе Microsoft выпускает версию 4.0 и делает все, что делала 3.5, плюс немного больше. Будет ли это работать? Похоже, что он полагается на установку 3.5, но сломается на машине, где установлена более новая версия без установки 3.5.
@ Джаред - полностью согласен. Определение версии фреймворка кажется довольно беспорядочным.
@Jared - и, следовательно, это просто предложение, а не окончательный ответ.
Раньше я проверял конкретную сборку в начале выполнения программы, но это только вызывало проблемы. Во-первых, если у пользователя даже не установлен .net, он не сможет запустить ваше приложение. Во-вторых, если у них нет нужной вам версии, вы вынуждены писать свой собственный код, чтобы либо загрузить его, либо перенаправить куда-нибудь для его загрузки. Эта проверка вызвала сбои на определенных машинах, и с тех пор я выпустил новую версию программного обеспечения, которая удалила эту проверку. См. Мой ответ ниже, чтобы найти лучшее решение.
@Kev, мне очень нравится твое решение. Спасибо за помощь.
В реестре код будет выглядеть примерно так:
RegistryKey key = Registry
.LocalMachine
.OpenSubKey("Software\Microsoft\NET Framework Setup\NDP\v3.5");
return (key != null);
Мне было бы любопытно, будет ли что-то из этого работать в среде со средним уровнем доверия (хотя я работаю с полным доверием, поэтому не имеет значения, над чем я сейчас работаю).
Я нашел хороший ресурс:
http://www.walkernews.net/2008/05/16/how-to-check-net-framework-version-installed/
Еще одна интересная находка - наличие здесь сборок:
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5
Можно подумать, что Microsoft встроит в фреймворк проверку на наличие «последней версии».
Без загрузки сборок и перехвата исключений (что происходит медленно) проверьте наличие изменений API класса между 2.0 и 3.5. Статус моно класса очень помогает в этом. Например, вы можете проверить GC.Collect Method (Int32, GCCollectionMode), который находится в mscorlib и был добавлен в 3.5.
Если вы хотите, чтобы была установлена определенная версия .net и вы могли контролировать распространение вашего приложения, вам действительно следует использовать ClickOnce. Он позволяет вам указать минимально необходимую версию платформы .Net, которая должна быть установлена, и она будет проверять только при ее установке, чтобы все ваши последующие запуски не были затруднены из-за ненужной проверки.
Кроме того, с ClickOnce вы получаете обновления бесплатно. Почему бы кому-то не захотеть его использовать?
Чтобы настроить приложение ClickOnce, просто щелкните проект правой кнопкой мыши в Visual Studio и перейдите в Параметры публикации. Это создаст специальную сборку вашего приложения, которую вы можете разместить на своем веб-сайте. Когда пользователи загружают программу, установщик проверяет наличие каких-либо предварительных условий, таких как .Net, для вас.
Все очень хорошо, но на самом деле не отвечает на вопрос ОП. Существуют сценарии (с которыми ОП столкнулся сам), когда вам нужно программно определить установленную версию фреймворка.
@ Кев, ты прав. Еще раз взглянув на вопрос, я вижу, что он хочет проверить, что если установлен, а не требовать, который нужно установить. Я оставлю свой ответ здесь в надежде, что любой, кто неправильно прочитает OP, сможет найти ответ, который они искали.
Один из вариантов - обнаружить 4.0 с помощью строки версии:
Environment.Version.CompareTo(new Version(4, 0));
то, поскольку 2.0 и 2.5 имеют общий номер версии CLR, их необходимо отличить, проверив реестр. Поскольку эти версии уже выпущены, строки, которые нужно искать, известны.
Разве System.Web.Extensions уже не является частью ASP.NET AJAX с номером версии 1.0.something?