Pergunta

Preciso determinar programaticamente se o .NET 3.5 está instalado.Eu pensei que seria fácil:

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

Que retorna "2.0.50727.1434", então não tive essa sorte...

Em minha pesquisa, descobri que existem algumas chaves de registro bastante obscuras que posso examinar, mas não tenho certeza se esse é o caminho a seguir.Alguém tem alguma sugestão?

Foi útil?

Solução

Você poderia tentar:

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

@usuario:Boa pergunta, vou tentar daqui a pouco.

Kevin

Outras dicas

Isso ocorre porque tecnicamente o .NET 3.5 é uma extensão da estrutura 2.0.A maneira mais rápida é incluir um assembly do .NET 3.5 e ver se ele quebra.

System.Web.Extensions

É um bom assembly que só está incluído na versão 3.5.Além disso, parece que você está usando o ASP.NET para executar esta verificação, isso realmente o limita porque você não conseguirá verificar o sistema de arquivos ou o registro em execução no modo protegido do ASP.NET.Ou você sempre pode tentar carregar de forma problemática um assembly do GAC que deveria estar apenas no .NET 3.5, mas você pode ter problemas com permissões novamente.

Este pode ser um daqueles momentos em que você se pergunta "o que estou tentando realizar?" E veja se existem rotas alternativas.

@Kev, gostei muito da sua solução.Obrigado pela ajuda.

Usando o registro o código ficaria mais ou menos assim:

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

Eu ficaria curioso para saber se algum deles funcionaria em um ambiente de confiança média (embora eu esteja trabalhando com total confiança, então não importa no que estou trabalhando atualmente).

@komradekatz, sua solução abaixo do MSDN para conveniência de outras pessoas que estejam pesquisando isso.Não gosto desta solução porque ela usa o agente do usuário para determinar a versão.Isso não é viável para o que preciso (estou escrevendo uma biblioteca de classes que precisa saber se o .NET 3.5 está instalado).Também questiono o quão confiável esta solução pode ser.

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

Na minha máquina isso gera:

Esta máquina possui a versão correta do .NET Framework 3.5.

A string userAgent desta máquina é:Mozilla/4.0 (compatível;MSIE 7.0;Windows NT 6.0;SLCC1;.NET CLR 2.0.50727;.NET CLR3.0.04506;InfoPath.2;.NET CLR1.1.4322;Zune 2.5).

Outra descoberta interessante é a presença de montagens aqui:

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

Você pensaria que a Microsoft criaria uma verificação da "versão mais recente" na estrutura.

Se você deseja exigir a instalação de uma versão específica do .net e pode controlar a distribuição do seu aplicativo, você realmente deve usar Clique uma vez.Ele permite que você especifique a versão mínima necessária do framework .Net que deve ser instalada, e só irá verificar quando estiver sendo instalado para que todas as suas inicializações subsequentes não sejam impedidas por uma verificação desnecessária.

Além disso, com ClickOnce você atualiza gratuitamente.Por que alguém não iria querer usá-lo?

Para configurar um aplicativo ClickOnce, basta clicar com o botão direito no projeto no Visual Studio e ir para Configurações de publicação.Isso criará uma versão especial do seu aplicativo que você poderá colocar no seu site.Quando os usuários baixam o programa, o instalador verifica se há pré-requisitos como .Net para você.

Uma opção é detectar 4.0 usando a string de versão:

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

então, como 2.0 e 2.5 compartilham um número de versão CLR, eles precisam ser diferenciados verificando o registro.Como essas versões já foram lançadas, as strings a serem procuradas são conhecidas.

Sem nenhum carregamento de assembly e captura de exceções (o que é lento), verifique se há alterações na API da classe entre 2.0 e 3.5. Status de classe mono é muito útil para isso.Por exemplo, você pode verificar GC.Collect Method (Int32, GCCollectionMode) que está no mscorlib e foi adicionado em 3.5.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top