【问题标题】:What's the foolproof way to tell which version(s) of .NET are installed on a production Windows Server?判断生产 Windows Server 上安装了哪些版本的 .NET 的万无一失的方法是什么?
【发布时间】:2010-09-13 11:37:32
【问题描述】:

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

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

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

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

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

【问题讨论】:

标签: .net windows deployment


【解决方案1】:

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

仅此而已。

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

【讨论】:

  • -如果它是生产服务器,他甚至可能无法访问它-在生产服务器上浏览随机站点是一个很大的禁忌-该站点仅提供最高的 .Net 版本;他想要所有这些
  • 问题,看起来,这种方法只会告诉你你拥有的最新版本是什么。我在 2.0、3.0、3.5 和(可悲的)甚至 1.1 中部署代码。虽然目标是最终升级所有内容,但目前可悲的事实是我需要所有不同的并行版本。
  • 虽然我同意这个解决方案可能不适合生产服务器,但我赞成它,因为它肯定是开发机器(我经常使用它)最简单和最快的方法。当前版本的脚本成功检测到我安装的所有不同版本的 .NET。
  • 来自所提供 URL 的用户代理字符串:Mozilla/5.0(兼容;MSIE 10.0;Windows NT 6.1;WOW64;Trident/6.0)。 Bu-ga-ga,那么,安装了哪些 .NET Framework 版本?要达到预期效果需要将 IE 切换到兼容模式。
  • Scott Hanselman 确实建立了他的诚意,所以我不会称其为“随机网站”。 (此外,他还提供了源代码。)但这个应用程序确实需要互联网连接,而锁定在法拉第笼中的主机经常缺乏这种连接。
【解决方案2】:

您可以按照blog entry 以编程方式检查注册表和其他一些内容。

要查看的注册表项是

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

【讨论】:

  • 我不知道 - 这是否也涵盖 1.1?
  • 我可以在我的系统上的这个注册表项下看到 1.1 的详细信息,所以我会说它确实涵盖了 1.1
  • 是的,在 ...\NDP\v4\Full\ 下查看,然后在 version 中我可以看到我有 v 4.5.5... TargetVersion 设置为 4.0.0
【解决方案3】:

here找到答案:

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

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

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

dir %WINDIR%\Microsoft.Net\Framework\v* /O:-N /B

【讨论】:

【解决方案4】:

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

%systemroot%\Microsoft.NET\Framework

然后搜索:

Mscorlib.dll

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

【讨论】:

  • 这似乎是区分版本 4 / 4.5+ 的最简单方法,否则,对于安装的概述,@K.Dias 答案对我有用:dir %windir%\@987654322 @ \framework\v* /O:-N /B
【解决方案5】:

微软的方式是这样的:

MSDN: How to determine Which .NET Framework Versions Are Installed(将您定向到以下注册表项:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...

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

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

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

【讨论】:

  • 此方法不再适用于 4.5.1 及更高版本
  • @Okuma.Scott - 我已经更新了官方 MSDN 说明的链接。
【解决方案6】:

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

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

【讨论】:

    【解决方案7】:

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

    【讨论】:

    • 仅部署该可执行文件是否存在任何(许可)问题?它没有任何依赖关系可言。
    • clrver 没用,因为它在撒谎。它说 4.0.* 表示 4.5/4.6
    【解决方案8】:

    有关如何执行此操作的 Microsoft 官方答案位于 KB article 318785

    【讨论】:

      【解决方案9】:

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

      【讨论】:

        【解决方案10】:

        检测.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

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

        【讨论】:

          【解决方案11】:

          另外,请参阅 Stack Overflow 问题 How to detect what .NET Framework versions and service packs are installed?,其中还提到:

          知识库文章[如何确定安装了 Microsoft .NET Framework 的哪些版本和服务包级别][2]

          对此问题有 Microsoft 官方回答

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

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

          【讨论】:

            【解决方案12】:

            要确定您的服务器是否支持 .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>
            

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

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

            【讨论】:

              【解决方案13】:

              要获取已安装的 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 ?
              【解决方案14】:

              奇怪的是,当 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;
              }
              

              【讨论】:

                【解决方案15】:

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

                【讨论】:

                  【解决方案16】:

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

                  这为文件夹提供了诸如v2.0.50727 之类的名称,我相信它会提供详细的版本信息。

                  【讨论】:

                  • 这可能是正确的方法,但“如果?”在我的脑海中说“如果文件在那里但框架并没有真正'安装'并且一些无知的管理员认为复制文件是这样做的方法吗?”
                  【解决方案17】:

                  如果您想查找 .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");
                  
                          }
                      }
                  }
                  

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

                  【讨论】:

                  【解决方案18】:

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

                  【讨论】:

                    【解决方案19】:

                    我发现这个非常有用。这是source

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2011-03-23
                      • 1970-01-01
                      • 2011-01-27
                      • 2011-08-22
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-09-16
                      相关资源
                      最近更新 更多