什么';判断生产Windows服务器上安装了哪个版本的.NET是最简单的方法吗?
这个问题与其说与编程相关,不如说与部署相关 我发现自己与公司的团队进行了大量交谈,他们的工作是维护我们的Windows生产服务器并在其上部署代码。出于法律和法规遵从性原因,我对服务器没有直接的可见性或任何控制权,因此我唯一能告诉他们安装了哪个.NET版本的方法是通过我向该组提供的指示 到目前为止,我能想到的所有判断安装了哪个版本的方法(检查与1.1或2.0匹配的管理工具,检查“添加/删除程序”列表中的条目,检查是否存在c:\Windows\Microsoft.NET下的目录)都有缺陷(我见过至少有一台机器在管理工具下有2.0版本,但没有2.0版本的条目——这种方法并没有告诉你关于3.0+的任何信息,“添加/删除程序”列表可能与现实不同步,目录的存在也不一定意味着什么) 考虑到我通常需要提前知道这些信息(发现“oops,这一个没有您需要的所有版本和服务包”在短时间的维护窗口中不能很好地工作),我必须“通过代理”进行检查既然我不能直接进入服务器,那么判断哪个版本最简单的方法是什么NET安装在生产Windows服务器上?最好是使用框架安装的某种内在方法,因为它会更快,不需要加载某种实用程序,而且如果框架未正确安装但仍有文件,这种方法肯定会失败(也就是说,有一个目录,其中有gacutil.exe,但该版本的框架并没有真正“安装”)什么';判断生产Windows服务器上安装了哪个版本的.NET是最简单的方法吗?,.net,windows,deployment,.net,Windows,Deployment,这个问题与其说与编程相关,不如说与部署相关 我发现自己与公司的团队进行了大量交谈,他们的工作是维护我们的Windows生产服务器并在其上部署代码。出于法律和法规遵从性原因,我对服务器没有直接的可见性或任何控制权,因此我唯一能告诉他们安装了哪个.NET版本的方法是通过我向该组提供的指示 到目前为止,我能想到的所有判断安装了哪个版本的方法(检查与1.1或2.0匹配的管理工具,检查“添加/删除程序”列表中的条目,检查是否存在c:\Windows\Microsoft.NET下的目录)都有缺陷(我见过至少
编辑:在框架中没有一个很好的简单的内在方法来实现这一点,有谁知道一个好的、轻量级的、不需要安装的程序可以发现这个问题吗?我可以想象有人可以很容易地编写一个程序,但如果已经有了,那就更好了。OneTouch部署将完成所有先决条件的检测和安装。最好使用一个预先制定的解决方案,而不是尝试重新部署我是你自己的。尝试推出自己的版本可能会导致问题,因为你键入的任何东西都可能会随着修补程序或service pack而更改。很可能Microsoft有一些启发式方法来确定正在运行的版本。这可能是一种很难找到版本的方法,但我一直认为所有版本都安装到了
:\WINDOWS\Microsoft.NET\Framework
这提供了带有名称的文件夹,如
v2.0.50727
,我认为这些文件夹提供了详细的版本信息。您可以通过编程方式检查注册表和一些其他内容
要查看的注册表项是
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...]
您应该在要查找此信息的服务器上打开IE,然后转到以下站点: 就这些
该站点有一个脚本,可以查看浏览器的“UserAgent”,找出您已安装(或未安装)的.NET Framework的版本(如果有),并自动显示它(如果您选择下载.NET Framework,则计算总大小).微软关于如何做到这一点的官方答案在中。微软的做法是: (这会将您指向以下注册表项:
HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\…
)
如果你想要万无一失,那是另外一回事了。我不会担心框架文件夹的XPo.1如果有人这样做,我会认为计算机坏了。< / P> 最简单的方法是编写一个小程序,使用每个版本的.NET和您关心的库并运行它们
对于无安装方法,是一个优秀的工具。它可以创建小型无运行时所需的exe。它可以自动执行上面MS KB文章中描述的检查。这里介绍了检测.NET 3.0的官方方法 有缺陷,因为它要求调用方具有注册表访问权限 MSDN还提到了一种通过检查用户代理字符串来检测.NET 3.5的技术:
我认为微软应该做得更好。如果你要检查的机器安装了.NET SDK,你可以使用SDK命令提示符运行程序
CLRVer.exe
,就像迪恩说的,你可以查看注册表并做他做的事情。要检查他是否真的安装了CLR.NET Framework,你可以应在%SystemRoot%\System32
目录中查找MSCorEE.dll
文件。根据,解决方案是在资源管理器窗口中输入以下内容:
%systemroot%\Microsoft.NET\Framework
然后搜索:
Mscorlib.dll
…然后右键单击/转到每个结果的版本选项卡。奇怪的是,我在1.1问世时(七年前是什么?)编写了一些代码来实现这一点,并在2.0问世时对其进行了一些调整。由于我们不再管理我们的服务器,我已经多年没有看过它了 这不是万无一失的,但我还是发布了它,因为我觉得它很幽默;在.NET中更容易实现,在Powershell中更容易实现
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;
}
另外,请参阅堆栈溢出问题,其中还提到: 在知识库文章[如何确定安装了Microsoft.NET Framework的哪些版本和service pack级别][2]中有Microsoft对此问题的官方答案 文章ID:318785-上次审阅:2008年11月7日-修订版:20.1如何确定安装了.NET Framework的哪些版本以及是否应用了service Pack 不幸的是,它似乎不起作用,因为
mscorlib。
dir %WINDIR%\Microsoft.Net\Framework\v*
dir %WINDIR%\Microsoft.Net\Framework\v* /O:-N /B
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);
}
}
}
}
}
}
}
}
}
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");
}
}
}
using System.Web.Mvc;
namespace DotnetVersionTest.Controllers
{
public class DefaultController : Controller
{
public string Index()
{
return "simple .NET version test...";
}
}
}
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
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
}