在生产Windows服务器上安装.NET的哪个版本有哪些安全的方法?

这个问题不像编程相关,因为它与部署有关。

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

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

鉴于我通常需要知道这些事情是提前到位(发现“哎呀,这个没有你需要的所有版本和服务包”在短期维护窗口中并不能很好地工作),我必须因为我无法直接访问服务器,请检查“通过代理服务器”,在生产Windows服务器上安装.NET的哪个版本的安全方法是什么? 最好是使用框架安装的一些固有的方法,因为它会更快,而且不需要某种加载工具,而且如果框架没有正确安装,但仍然有文件,这肯定会失败。 ,有一个目录和gacutil.exe是在那里,但该框架的版本是不是真的“安装”)

编辑:缺乏一个好的万无一失内在的方式来做到这一点内置到框架(S),没有人知道一个好的,轻量级的,没有安装所需的程序,可以find这个? 我可以想象有人可以很容易地写一个,但如果已经存在,那会更好。

你应该打开你正在寻找这个信息的服务器上的IE浏览器,并去这个网站: http : //www.hanselman.com/smallestdotnet/

这一切都需要。

该网站有一个脚本,看起来您的浏览器的“UserAgent”,并找出什么版本(如果有)的.NET框架,你有(或没有)安装,并自动显示(然后计算总大小,如果你select下载.NET Framework)。

你可以按照这个博客条目以编程方式检查registry和其他一些东西。

registry键是看

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

从这里find答案:

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

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

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

要么

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

微软的方式是这样的:

MSDN:如何确定哪些.NET Framework版本安装 (将您引导至以下registry项: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...

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

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

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

根据CodeTrawler的回答 ,解决scheme是将以下内容input到资源pipe理器窗口中:

%SYSTEMROOT%\ Microsoft.NET \框架

然后search:

mscorlib.dll中

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

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

使用这个“好,轻量级,不需要安装的程序”

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

有关如何执行此操作的官方Microsoft答案位于知识库文章318785中 。

OneTouch部署将完成所有先决条件的检测和安装。 最好是用预先制定的解决scheme,而不是试图推出自己的解决scheme。 尝试推出自己的产品可能会导致问题,因为无论您使用的是哪种产品,都可能会因修复程序或服务包而改变。 可能微软有一些启发式的决定什么版本正在运行。

这里介绍检测.NET 3.0的官方方法

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

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

MSDN也提到了通过检查用户代理string来检测.NET 3.5的技术:

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

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

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

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

文章编号:318785 – 最后修改:2008年11月7日 – 修订:20.1如何确定安装了哪些版本的.NET Framework以及是否应用了Service Pack。

不幸的是,它似乎没有工作,因为在2.0目录中的mscorlib.dll版本有一个2.0版本,即使3.5 SP1安装在3.0或3.5目录中没有mscorlib.dll版本…为什么微软官方的回答会如此错误吗?

要确定您的服务器对.NET Framework 4.5及更高版本(通过4.5.2testing)的支持, 请执行以下操作如果服务器上没有registry访问权限 ,但具有对该服务器的应用程序发布权限,请创build一个带有微不足道的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 。 如果你的服务器支持目标框架,那么简单的string将显示从你的微不足道的控制器。 如果没有,您将收到如下错误:

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

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

要获得安装的dotnet版本,
创build控制台应用程序。 添加这个类运行

 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 } 

奇怪的是,我写了一些代码在1.1出来的时候(七年前是什么时候?)在2.0出来的时候调整了一些代码。 多年以来我没有看过它,因为我们不再pipe理我们的服务器。

这不是万无一失的,但我仍然发布它,因为我觉得它很幽默, 因为在.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; } 

那么就像Dean说的那样,你可以看看registry,做他所做的事情。 要检查他是否确实安装了CLR .NET Framework,应该在%SystemRoot%\System32目录中查找MSCorEE.dll文件。

这可能是一个讨厌的方式来find版本,但我总是有一个印象,所有的版本都安装到<root>:\WINDOWS\Microsoft.NET\Framework

这提供了文件夹名称,如v2.0.50727我相信给详细的版本信息。

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

否则,你可以通过这样的查询find.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"); } } } 

然后控制台结果会告诉你哪些版本已经安装,并且可以用于你的部署。 这个代码也派上用场,因为您将它们作为保存的解决scheme,随时可以在将来进行检查。

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