¿Cuál es la manera infalible de saber qué versiones de .NET están instaladas en un servidor Windows de producción?

99

Esta pregunta no está tanto relacionada con la programación como con la implementación.

Me encuentro conversando mucho con el grupo de mi empresa cuyo trabajo es mantener nuestros servidores de producción de Windows e implementar nuestro código en ellos. Por razones legales y de cumplimiento, no tengo visibilidad directa ni control alguno sobre los servidores, por lo que la única forma de saber qué versiones de .NET están instaladas en cualquiera de ellos es a través de las instrucciones que le doy a ese grupo.

Hasta ahora, todos los métodos que se me ocurren para saber qué versión (s) están instaladas (verifique que las Herramientas administrativas coincidan con 1.1 o 2.0, verifique las entradas en la lista "Agregar o quitar programas", verifique la existencia del directorios en c: \ Windows \ Microsoft.NET) tienen fallas (he visto al menos una máquina con 2.0 pero no 2.0 entradas en Herramientas administrativas, y ese método no le dice nada sobre 3.0+, la lista "Agregar o quitar programas" puede perder la sincronización con la realidad, y la existencia de los directorios no significa necesariamente nada).

Dado que generalmente necesito saber que estas cosas están en su lugar de antemano (descubrir que "uy, este no tiene todas las versiones y paquetes de servicio que necesita" realmente no funciona bien con períodos de mantenimiento cortos) y tengo que Hacer la verificación "por proxy" ya que no puedo acceder a los servidores directamente, ¿cuál es la manera infalible de saber qué versión (s) de .NET están instaladas en un servidor Windows de producción? Preferiblemente, alguna forma intrínseca de hacerlo utilizando lo que instala el marco, ya que será más rápido y no necesitará ningún tipo de utilidad para cargarse y también un método que definitivamente fallará si los marcos no están instalados correctamente pero aún tienen archivos en su lugar (es decir, , hay un directorio y gacutil.exe está insertado allí, pero esa versión del marco no está realmente "instalada")

EDITAR: En ausencia de una buena forma intrínseca infalible de hacer esto incorporada en el marco (s), ¿alguien conoce un programa bueno, liviano y que no requiere instalación que pueda descubrir esto? Me imagino que alguien podría escribir uno fácilmente, pero si ya existe, sería aún mejor.

Tom Kidd
fuente
1
Investigué esto hace un tiempo y no pude encontrar una manera definitiva de hacerlo. Me interesaría ver qué respuestas obtenemos.
Kev
Posible duplicado de ¿Cómo detectar qué versiones de .NET Framework y service packs están instalados? - la pregunta canónica (aunque es 17 días más joven).
Peter Mortensen

Respuestas:

54

Debe abrir IE en el servidor para el que está buscando esta información e ir a este sitio: http://www.hanselman.com/smallestdotnet/

Eso es todo lo que se necesita.

El sitio tiene una secuencia de comandos que busca el "UserAgent" de su navegador y determina qué versión (si existe) de .NET Framework tiene (o no) instalada, y la muestra automáticamente (luego calcula el tamaño total si lo eligió para descargar .NET Framework).

Vaibhav
fuente
19
- si es un servidor de producción, es posible que ni siquiera tenga acceso a él - navegar por sitios aleatorios en el servidor prod es un gran no-no - ese sitio solo ofrece la versión .Net más alta; los quiere a todos
Franci Penov
1
El problema, al parecer, con ese enfoque es que solo te dice cuál es la última versión que tienes. Implemento código en 2.0, 3.0, 3.5 y (lamentablemente) incluso 1.1. Aunque el objetivo es que todo se actualice eventualmente, el hecho triste por ahora es que necesito todas las diferentes versiones paralelas.
Tom Kidd
1
Aunque estoy de acuerdo en que esta solución puede no ser apropiada para servidores de producción, la voté porque es sin duda el método más simple y rápido para máquinas de desarrollo (en las que lo he usado a menudo). La versión actual del script detectó con éxito todas las diferentes versiones de .NET que había instalado.
kmote
Cadena de agente de usuario de la URL proporcionada: Mozilla / 5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident / 6.0) . Bu-ga-ga, entonces, ¿qué versiones de .NET Framework están instaladas? Para lograr el resultado esperado, es necesario cambiar IE al modo compatible.
Mosc
1
Scott Hanselman ciertamente ha establecido su buena fe, por lo que no lo llamaría un "sitio aleatorio". (Además, hace que el código fuente esté disponible). Pero esta aplicación requiere una conexión a Internet, de la que carecen con frecuencia los hosts encerrados en una jaula de Faraday.
Robert Calhoun
24

Puede verificar mediante programación el registro y algunas otras cosas según esta entrada de blog .

La clave de registro para mirar es

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...]
Ed Guiness
fuente
No puedo decirlo, ¿esto también cubre 1.1?
Tom Kidd
1
Puedo ver 1.1 detalles bajo esta clave de registro en mi sistema, así que diría que cubre 1.1
Niall Connaughton
Sí, mirando debajo de ... \ NDP \ v4 \ Full \, luego en la versión pude ver que tenía v 4.5.5 ... The TargetVersion se establece en 4.0.0
Off The Gold
19

Respuesta encontrada desde aquí :

Compruebe qué versión de .NET Framework está instalada

Abra el símbolo del sistema y copie y pegue una de las siguientes líneas de comando

dir %WINDIR%\Microsoft.Net\Framework\v*

o

dir %WINDIR%\Microsoft.Net\Framework\v* /O:-N /B
K.Dias
fuente
Exactamente lo que necesitaba
PandaWood
13
4.5 y 4.5.1 están instalados en lugar de 4.0, por lo que esta solución puede ser engañosa. msdn.microsoft.com/en-us/library/5a4x27ek%28v=vs.110%29.aspx
Nick Patsaris
15

Según la respuesta de CodeTrawler , la solución es ingresar lo siguiente en una ventana del explorador:

% systemroot% \ Microsoft.NET \ Framework

Luego busque:

Mscorlib.dll

... y haga clic con el botón derecho / vaya a la pestaña de versión para cada resultado.

Jon Cage
fuente
Esta parece ser la forma más fácil de diferenciar entre la versión 4 / 4.5+; de lo contrario, para obtener una descripción general de lo que está instalado, la respuesta de @ K.Dias funcionó para mí: dir% windir% \ microsoft.net \ framework \ v * / O : -N / B
Timothy Lee Russell
15

La forma de Microsoft es la siguiente:

MSDN: Cómo determinar qué versiones de .NET Framework están instaladas (que lo dirige a la siguiente clave de registro:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\... )

Si quieres infalible eso es otra cosa. No me preocuparía por una copia de la carpeta del marco. Si alguien hiciera eso, consideraría que la computadora está rota.

La forma más infalible sería escribir un pequeño programa que use cada versión de .NET y las bibliotecas que le interesan y ejecutarlas.

Para un método sin instalación, PowerBasic es una herramienta excelente. Crea pequeños ejecutables que no requieren tiempo de ejecución. Podría automatizar las comprobaciones descritas en el artículo de MS KB anterior.

bruceatk
fuente
Este método ya no funciona para las versiones 4.5.1 y posteriores
Scott Solmer
@ Okuma.Scott - He actualizado el enlace a las instrucciones oficiales de MSDN.
kmote
3

Si la máquina que desea verificar tiene .NET SDK instalado, puede usar un símbolo del sistema del SDK y ejecutar el programa CLRVer.exe.

Jim Deville
fuente
1
¿Hay algún problema (de licencia) con la implementación de ese ejecutable? No tiene dependencias de las que hablar.
1
clrver es inútil, porque miente. Dice 4.0. * Para 4.5 / 4.6
Roman Starkov
1

La implementación de OneTouch hará toda la detección e instalación de los requisitos previos. Probablemente sea mejor optar por una solución prefabricada que intentar hacer la tuya propia. Tratar de rodar el suyo propio puede generar problemas porque cualquier cosa que ingrese puede cambiar con una revisión o paquete de servicio. Es probable que Microsoft tenga alguna heurística para determinar qué versión se está ejecutando.

Orion Adrian
fuente
1

Además, consulte la pregunta de Stack Overflow ¿ Cómo detectar qué versiones de .NET Framework y service packs están instalados? que también menciona:

Hay una respuesta oficial de Microsoft a esta pregunta en el artículo de la base de conocimientos [Cómo determinar qué versiones y niveles de paquetes de servicio de Microsoft .NET Framework están instalados] [2]

Id. De artículo: 318785 - Última revisión: 7 de noviembre de 2008 - Versión: 20.1 Cómo determinar qué versiones de .NET Framework están instaladas y si se han aplicado Service Packs.

Desafortunadamente, no parece funcionar, porque la mscorlib.dllversión en el directorio 2.0 tiene una versión 2.0, y no hay ninguna mscorlib.dllversión en los directorios 3.0 o 3.5 a pesar de que 3.5 SP1 está instalado ... ¿Por qué la respuesta oficial de Microsoft sería tan mal informado?

luego
fuente
1

Para determinar el soporte de su servidor para .NET Framework 4.5 y versiones posteriores (probado a través de 4.5.2): Si no tiene acceso al Registro en el servidor , pero tiene derechos de publicación de aplicaciones en ese servidor, cree una aplicación MVC 5 con un trivial controlador, así:

using System.Web.Mvc;

namespace DotnetVersionTest.Controllers
{
    public class DefaultController : Controller
    {
        public string Index()
        {
            return "simple .NET version test...";
        }
    }
}

Luego, en su Web.config, recorra las versiones de .NET Framework deseadas en la siguiente sección, cambiando los targetFrameworkvalores como desee:

<system.web>
    <customErrors mode="Off"/>
    <compilation debug="true" targetFramework="4.5.2"/>
    <httpRuntime targetFramework="4.5.2"/>
</system.web>

Publique cada destino en su servidor, luego busque <app deploy URL>/Default. Si su servidor es compatible con el marco de destino, entonces la cadena simple se mostrará desde su controlador trivial. De lo contrario, recibirá un error como el siguiente:

Ejemplo de .NET 4.5.2 no compatible en el servidor

Entonces, en este caso, mi servidor de destino aún no es compatible con .NET Framework 4.5.2.

dave_k_smith
fuente
1

Para obtener la versión de dotnet instalada, cree
una aplicación de consola. Agregar esta clase Ejecutar eso

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    public class GetDotNetVersion
    {
        public static void Get45PlusFromRegistry()
        {
            const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
            {
                if (ndpKey != null && ndpKey.GetValue("Release") != null)
                {
                    Console.WriteLine(".NET Framework Version: " + CheckFor45PlusVersion((int)ndpKey.GetValue("Release")));
                }
                else
                {
                    Console.WriteLine(".NET Framework Version 4.5 or later is not detected.");
                }
            }
        }

        // Checking the version using >= will enable forward compatibility.
        private static string CheckFor45PlusVersion(int releaseKey)
        {
            if (releaseKey >= 394802)
                return "4.6.2 or later";
            if (releaseKey >= 394254)
            {
                return "4.6.1";
            }
            if (releaseKey >= 393295)
            {
                return "4.6";
            }
            if ((releaseKey >= 379893))
            {
                return "4.5.2";
            }
            if ((releaseKey >= 378675))
            {
                return "4.5.1";
            }
            if ((releaseKey >= 378389))
            {
                return "4.5";
            }
            // This code should never execute. A non-null release key shoul
            // that 4.5 or later is installed.
            return "No 4.5 or later version detected";
        }
    }
    // Calling the GetDotNetVersion.Get45PlusFromRegistry method produces 
    // output like the following:
    //       .NET Framework Version: 4.6.1
}
Esqueleto Metálico
fuente
última versión 4.7.2?
Kiquenet
0

Curiosamente, escribí un código para hacer esto cuando salió 1.1 (¿qué era eso, hace siete años?) Y lo modifiqué un poco cuando salió 2.0. No lo he mirado en años porque ya no administramos nuestros servidores.

No es infalible, pero lo estoy publicando de todos modos porque lo encuentro gracioso; ya que es más fácil de hacer en .NET y aún más fácil en Power Shell.

bool GetFileVersion(LPCTSTR filename,WORD *majorPart,WORD *minorPart,WORD *buildPart,WORD *privatePart)
{
    DWORD dwHandle;
    DWORD dwLen = GetFileVersionInfoSize(filename,&dwHandle);
    if (dwLen) {
        LPBYTE lpData = new BYTE[dwLen];
        if (lpData) {
            if (GetFileVersionInfo(filename,0,dwLen,lpData)) {
                UINT uLen;  
                VS_FIXEDFILEINFO *lpBuffer;  
                VerQueryValue(lpData,_T("\\"),(LPVOID*)&lpBuffer,&uLen);  
                *majorPart = HIWORD(lpBuffer->dwFileVersionMS);
                *minorPart = LOWORD(lpBuffer->dwFileVersionMS);
                *buildPart = HIWORD(lpBuffer->dwFileVersionLS);
                *privatePart = LOWORD(lpBuffer->dwFileVersionLS);
                delete[] lpData;
                return true;
            }
        }
    }
    return false;
}

int _tmain(int argc,_TCHAR* argv[])
{
    _TCHAR filename[MAX_PATH];
    _TCHAR frameworkroot[MAX_PATH];
    if (!GetEnvironmentVariable(_T("systemroot"),frameworkroot,MAX_PATH))
        return 1;
    _tcscat_s(frameworkroot,_T("\\Microsoft.NET\\Framework\\*"));
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile(frameworkroot,&FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
        return 2;
    do {
        if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
            _tcslen(FindFileData.cAlternateFileName) != 0) {
            _tcsncpy_s(filename,frameworkroot,_tcslen(frameworkroot)-1);
            filename[_tcslen(frameworkroot)] = 0;
            _tcscat_s(filename,FindFileData.cFileName);
            _tcscat_s(filename,_T("\\mscorlib.dll"));
            WORD majorPart,minorPart,buildPart,privatePart;
            if (GetFileVersion(filename,&majorPart,&minorPart,&buildPart,&privatePart )) {
                _tprintf(_T("%d.%d.%d.%d\r\n"),majorPart,minorPart,buildPart,privatePart);
            }
        }
    } while (FindNextFile(hFind,&FindFileData) != 0);
    FindClose(hFind);
    return 0;
}

fuente
0

Bueno, como dijo Dean, puedes mirar el registro y hacer lo que él hizo. Para comprobar si realmente tiene CLR .NET Framework instalado, debe buscar el MSCorEE.dllarchivo en el %SystemRoot%\System32directorio.

Bruno Costa
fuente
0

Probablemente sea una forma desagradable de averiguar versiones, pero siempre tuve la impresión de que todas las versiones se instalaron <root>:\WINDOWS\Microsoft.NET\Framework.

Esto proporciona carpetas con nombres v2.0.50727que creo que dan información detallada sobre la versión.

Decano
fuente
1
Y esa podría ser la manera correcta, pero el "¿y si?" en mi cabeza dice "¿qué pasa si los archivos están allí pero el Framework no está realmente 'instalado' y algún administrador despistado pensó que copiar los archivos era la forma de hacerlo?"
Tom Kidd
0

Si desea encontrar versiones anteriores a .NET 4.5, use el código para una aplicación de consola. Me gusta esto:

using System;
using System.Security.Permissions;
using Microsoft.Win32;

namespace findNetVersion
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
                     RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            {
                foreach (string versionKeyName in ndpKey.GetSubKeyNames())
                {
                    if (versionKeyName.StartsWith("v"))
                    {

                        RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                        string name = (string)versionKey.GetValue("Version", "");
                        string sp = versionKey.GetValue("SP", "").ToString();
                        string install = versionKey.GetValue("Install", "").ToString();
                        if (install == "") //no install info, must be later version
                            Console.WriteLine(versionKeyName + "  " + name);
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            }
                        }
                        if (name != "")
                        {
                            continue;
                        }
                        foreach (string subKeyName in versionKey.GetSubKeyNames())
                        {
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name = (string)subKey.GetValue("Version", "");
                            if (name != "")
                                sp = subKey.GetValue("SP", "").ToString();
                                install = subKey.GetValue("Install", "").ToString();
                            if (install == "") //no install info, ust be later
                                Console.WriteLine(versionKeyName + "  " + name);
                            else
                            {
                                if (sp != "" && install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                }
                                else if (install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

De lo contrario, puede encontrar .NET 4.5 o posterior consultando de esta manera:

private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
       RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"))
    {
        int releaseKey = (int)ndpKey.GetValue("Release");
        {
            if (releaseKey == 378389)

                Console.WriteLine("The .NET Framework version 4.5 is installed");

            if (releaseKey == 378758)

                Console.WriteLine("The .NET Framework version 4.5.1  is installed");

        }
    }
}

Luego, el resultado de la consola le dirá qué versiones están instaladas y disponibles para usar con sus implementaciones. Este código también es útil porque los tiene como soluciones guardadas para cuando quiera verificarlo en el futuro.

Ronnie Petty
fuente
Por cierto, es posible que desee configurar Main en privado de esta manera: private static void Main (string [] args) {}
Ronnie Petty
Así es como Microsoft lo ha presentado en MSDN. msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx
Ronnie Petty
0

Entré en Windows Update y miré el historial de actualizaciones, sabiendo que el parche del servidor se mantiene actualizado. Busqué actualizaciones de .NET y me mostró exactamente qué versiones habían tenido actualizaciones, lo que me permitió concluir qué versiones estaban instaladas.

Kim K.
fuente
0

Encontré este bastante útil. aquí está la fuente

ingrese la descripción de la imagen aquí

Michael Bahig
fuente