哪种方法可以很容易地判断生产Windows Server上安装了.NET的哪个版本?


99

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

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

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

鉴于我通常需要提前知道这些事情(发现“哎呀,这个工具并没有您需要的所有版本和服务包”,因此在较短的维护时段内并不能很好地工作),我必须因为无法直接在服务器上进行检查,所以“通过代理”进行检查是什么安全的方法来判断生产Windows Server上安装了.NET的哪个版本?最好使用框架安装的某种内在方式,因为这样安装起来会更快,不需要加载某种实用程序,而且如果框架未正确安装但仍然有文件,则该方法肯定会失败(即,其中有一个目录,并在其中插入了gacutil.exe,但该框架的版本并未真正“安装”)

编辑:在没有一个很好的万无一失的内在方式来做到这一点内置在Framework(s)中,有人知道一个好的,轻量级,无需安装的程序可以找到这一点吗?我可以想象有人可以轻松编写一个,但是如果已经存在,那会更好。


1
我回想了一下,找不到一种确定的方法。我很想知道我们得到什么答案。
凯夫

可能重复的方法如何检测安装了哪些.NET Framework版本和Service Pack?-规范的问题(即使还不到17天)。
彼得·莫滕森

Answers:


54

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

这就是全部。

该站点具有一个脚本,该脚本看起来像浏览器的“ UserAgent”,并指出您已安装(或未安装).NET Framework的版本(如果有),并自动显示(如果选择,则计算总大小)下载.NET Framework)。


19
-如果是生产服务器,他甚至可能无法访问它-在生产服务器上浏览随机站点是一个很大的禁忌-该站点仅提供最高的.Net版本;他想要所有人
弗朗西·佩诺夫

1
这种方法的问题在于,它只能告诉您最新的版本。我在2.0、3.0、3.5和(甚至)1.1中部署代码。尽管目标是最终升级所有内容,但现在可悲的事实是我需要所有不同的并行版本。
汤姆·基德

1
尽管我同意该解决方案可能不适用于生产服务器,但我还是赞成它,因为它无疑是开发机器(我经常使用它)的最简单,最快的方法。当前版本的脚本已成功检测到我安装的所有.NET版本。
kmote 2012年

提供的URL中的用户代理字符串:Mozilla / 5.0(兼容; MSIE 10.0; Windows NT 6.1; WOW64; Trident / 6.0)。Bu-ga-ga,那么,安装了哪些.NET Framework版本?为了达到预期的结果,需要将IE切换到兼容模式。
Mosc 2013年

1
斯科特·汉瑟曼(Scott Hanselman)当然已经确立了自己的诚意,所以我不会将其称为“随机站点”。(此外,他还提供了源代码。)但是此应用程序确实需要Internet连接,而锁定在法拉第笼中的主机经常缺少该连接。
罗伯特·卡尔洪

24

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

要查看的注册表项是

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...]

我不知道-这还涵盖1.1吗?
汤姆·基德

1
我可以在系统上的此注册表项下看到1.1详细信息,所以我想说它确实涵盖了1.1
Niall Connaughton

是的,在... \ NDP \ v4 \ Full \下查看,然后在该版本中 我看到的是v 4.5.5 ... TargetVersion设置为4.0.0
黄金


15

按照CodeTrawler的回答,解决方案是在浏览器窗口中输入以下内容:

%systemroot%\ Microsoft.NET \ Framework

然后搜索:

Mscorlib.dll

...,然后右键单击/转到每个结果的版本标签。


这似乎是区分版本4 / 4.5+的最简单方法,否则,对于已安装内容的概述,@ K.Dias答案对我有用:dir%windir%\ microsoft.net \ framework \ v * / O :-N / B
蒂莫西·李·罗素

15

微软的方式是这样的:

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

如果您想要万无一失,那是另一回事。我不用担心framework文件夹的xcopy。如果有人这样做,我会认为计算机坏了。

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

对于无安装方法,PowerBasic是一个出色的工具。它创建小的没有运行时所需的exe。它可以自动执行上面MS KB文章中所述的检查。


此方法不再适用于4.5.1及更高版本
Scott Solmer 2014年

@ Okuma.Scott-我已经更新了MSDN官方说明的链接。
kmote 2015年


3

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


1
仅部署该可执行文件是否有任何(许可)问题?它没有任何依赖可言。

1
clrver是无用的,因为它说谎。表示4.0 / *为4.5 / 4.6
Roman Starkov


1

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



1

另外,请参阅堆栈溢出问题如何检测到已安装的.NET Framework版本和Service Pack?其中还提到:

知识库文章[如何确定已安装Microsoft .NET Framework的哪个版本和Service Pack级别]是Microsoft对此问题的官方解答。[2]

文章ID:318785-最后审阅:2008年11月7日-修订:20.1如何确定安装了.NET Framework的版本以及是否已应用Service Pack。

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


1

要确定服务器对.NET Framework 4.5和更高版本(通过4.5.2进行了测试)的支持,请执行以下操作如果您没有服务器上的Registry访问权限,但具有对该服务器的应用发布权限,请创建一个琐碎的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。如果您的服务器支持目标框架,那么简单的字符串将从您的普通Controller中显示。如果没有,您将收到类似以下的错误:

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

因此,在这种情况下,我的目标服务器尚不支持.NET Framework 4.5.2。


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
}

最新版本4.7.2?
Kiquenet '19

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

0

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


0

找出版本可能是一种令人讨厌的方式,但是我总是对所有版本都已安装到印象<root>:\WINDOWS\Microsoft.NET\Framework

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


1
那可能是正确的方法,但是“如果?” 在我的脑海中说:“如果有文件但没有真正“安装”框架,又有一些笨拙的管理员认为将文件复制过来是怎么办?”
汤姆·基德

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

        }
    }
}

然后,控制台结果将告诉您已安装哪些版本,并且可用于您的部署。该代码也派上用场,因为您可以将它们作为保存的解决方案,以备将来随时检查。


顺便说一句,您可能希望像这样将Main设置为private:private static void Main(string [] args){}
Ronnie Petty 2013年

这几乎就是Microsoft在MSDN上的布局方式。msdn.microsoft.com/zh-CN/library/hh925568%28v=vs.110%29.aspx
罗尼·佩蒂

0

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.