99

这个问题与其说是编程相关,不如说是与部署相关。

我发现自己与我公司的团队进行了很多交谈,他们的工作是维护我们的生产 Windows 服务器并在它们上部署我们的代码。出于法律和合规性原因,我对服务器没有直接的可见性或任何控制权,因此我可以判断其中安装了哪些 .NET 版本的唯一方法是通过我给该组的指示。

到目前为止,我能想到的所有方法来判断安装了哪些版本(检查与 1.1 或 2.0 匹配的管理工具,检查“添加/删除程序”列表中的条目,检查是否存在c:\Windows\Microsoft.NET 下的目录)有缺陷(我在管理工具下看到至少一台机器有 2.0 但没有 2.0 条目 - 而且该方法没有告诉您任何关于 3.0+ 的信息,即“添加/删除程序”列表可能与现实不同步,目录的存在并不一定意味着什么)。

鉴于我通常需要提前知道这些东西已经到位(发现“哎呀,这个没有你需要的所有版本和服务包”在维护窗口短的情况下并不能很好地工作),我必须由于我无法直接访问服务器,因此“通过代理”进行检查,判断生产 Windows Server 上安装了哪些版本的 .NET 的万无一失的方法是什么?最好是使用框架安装的一些内在方法来这样做,因为它会更快并且不需要加载某种实用程序,而且如果框架没有正确安装但仍然有文件(即,有一个目录和 gacutil.exe 是 inded 那里,但该版本的框架并没有真正“安装”)

编辑:在没有一个好的万无一失的内在方法来做到这一点内置到框架中的情况下,有没有人知道一个好的、轻量级的、不需要安装的程序可以找到这个?我可以想象有人可以很容易地写一个,但如果已经存在一个,那就更好了。

4

19 回答 19

54

您应该在要查找此信息的服务器上打开 IE,然后访问此站点:http ://www.hanselman.com/smallestdotnet/

这就是它所需要的。

该站点有一个脚本,可以查看您浏览器的“UserAgent”,并确定您安装(或未安装)的 .NET Framework 版本(如果有),并自动显示它(然后计算总大小,如果您选择下载 .NET 框架)。

于 2008-09-26T14:41:16.897 回答
24

您可以按照此博客条目以编程方式检查注册表和其他一些内容。

要查看的注册表项是

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...]
于 2008-09-26T14:35:16.850 回答
19

从这里找到答案:

检查安装了哪个 .NET Framework 版本

打开命令提示符并复制粘贴以下命令行之一

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

或者

dir %WINDIR%\Microsoft.Net\Framework\v* /O:-N /B
于 2013-09-13T17:18:33.480 回答
15

微软的方式是这样的:

MSDN:如何确定安装了哪些 .NET Framework 版本(将您定向到以下注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...:)

如果你想要万无一失,那是另一回事。我不会担心框架文件夹的 xcopy。如果有人这样做,我会认为电脑坏了。

最简单的方法是编写一个小程序,使用每个版本的 .NET 和您关心的库并运行它们。

对于免安装方法,PowerBasic是一款出色的工具。它创建了小的不需要运行时的 exe。它可以自动执行上面 MS 知识库文章中描述的检查。

于 2008-09-26T14:58:24.487 回答
15

根据CodeTrawler 的回答,解决方案是在资源管理器窗口中输入以下内容:

%systemroot%\Microsoft.NET\Framework

然后搜索:

mscorlib.dll

...并右键单击/转到每个结果的版本选项卡。

于 2009-06-01T16:07:54.267 回答
7

http://www.asoft.be/prod_netver.html

使用这个“好、轻量级、无需安装的程序”

于 2012-06-19T23:19:37.867 回答
3

有关如何执行此操作的 Microsoft 官方答案在KB 文章 318785中。

于 2008-09-26T14:58:14.237 回答
3

如果您要检查的机器安装了 .NET SDK,您可以使用 SDK 命令提示符并运行该程序CLRVer.exe

于 2008-09-26T17:29:42.920 回答
1

OneTouch 部署将完成所有先决条件的检测和安装。最好使用预制的解决方案,而不是尝试自己动手。尝试自行推出可能会导致问题,因为您键入的任何内容都可能因修补程序或服务包而改变。微软可能有一些启发式方法来确定正在运行的版本。

于 2008-09-26T14:34:14.700 回答
1

检测 .NET 3.0 的官方方法在此处描述

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

有缺陷,因为它要求调用者具有注册表访问权限。

MSDN 还提到了一种通过检查用户代理字符串来检测 .NET 3.5 的技术:

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

我认为微软应该做得比这更好。

于 2008-09-26T17:22:51.097 回答
1

另外,请参阅 Stack Overflow 问题如何检测安装了哪些 .NET Framework 版本和服务包?其中还提到:

在知识库文章[如何确定安装了 Microsoft .NET Framework 的版本和服务包级别][2] 中有Microsoft 官方对此问题的回答

文章 ID:318785 - 上次评论:2008 年 11 月 7 日 - 修订:20.1 如何确定已安装的 .NET Framework 版本以及是否已应用服务包。

不幸的是,它似乎不起作用,因为mscorlib.dll2.0 目录中的版本有 2.0 版本,mscorlib.dll即使安装了 3.5 SP1,3.0 或 3.5 目录中也没有版本......为什么微软官方的回答是如此误导?

于 2010-06-21T20:34:59.450 回答
1

要确定您的服务器对.NET Framework 4.5 及更高版本的支持(通过 4.5.2 测试):如果您在服务器上没有注册表访问权限,但对该服务器具有应用程序发布权限,请创建一个具有简单的 MVC 5 应用程序控制器,像这样:

using System.Web.Mvc;

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

然后在您的 Web.config 中,浏览下一部分中所需的 .NET Framework 版本,targetFramework根据需要更改值:

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

将每个目标发布到您的服务器,然后浏览到<app deploy URL>/Default. 如果您的服务器支持目标框架,那么简单的字符串将从您的普通控制器中显示。如果没有,您将收到如下错误:

服务器上不受支持的 .NET 4.5.2 示例

所以在这种情况下,我的目标服务器还不支持 .NET Framework 4.5.2。

于 2014-05-29T16:04:48.430 回答
1

要获取已安装的 dotnet 版本,请
创建控制台应用程序。添加此类运行

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
}
于 2016-10-07T08:43:05.840 回答
0

找出版本可能是一种讨厌的方式,但我一直认为所有版本都安装到<root>:\WINDOWS\Microsoft.NET\Framework.

这提供了带有名称的文件夹,例如v2.0.50727我认为可以提供详细版本信息的文件夹。

于 2008-09-26T14:34:45.447 回答
0

好吧,就像 Dean 说的,您可以查看注册表并执行他所做的操作。要检查他是否真的安装了 CLR .NET Framework,您应该MSCorEE.dll在目录中查找该文件%SystemRoot%\System32

于 2009-01-31T20:26:06.363 回答
0

奇怪的是,当 1.1 发布时,我写了一些代码来执行此操作(那是什么,七年前?)并在 2.0 发布时对其进行了一些调整。因为我们不再管理我们的服务器,所以我已经好几年没有看过它了。

这不是万无一失的,但无论如何我都会发布它,因为我觉得它很幽默;因为在 .NET 中更容易做到,在 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;
}
于 2010-04-22T18:56:16.780 回答
0

如果要查找 .NET 4.5 之前的版本,请使用控制台应用程序的代码。像这样:

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);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

否则,您可以通过如下查询找到 .NET 4.5 或更高版本:

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");

        }
    }
}

然后控制台结果将告诉您哪些版本已安装并可用于您的部署。这段代码也很方便,因为您可以将它们作为保存的解决方案,以便将来随时查看。

于 2013-11-29T17:55:16.320 回答
0

我进入 Windows Update 并查看了更新历史记录,知道服务器补丁是最新的。我扫描了 .NET 更新,它准确地向我显示了哪些版本有更新,这使我能够得出安装了哪些版本的结论。

于 2016-07-28T18:20:32.357 回答
0

我发现这个非常有用。这是来源

在此处输入图像描述

于 2018-06-28T09:37:38.323 回答