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

时间:2020-03-06 14:47:16  来源:igfitidea点击:

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

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

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

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

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

解决方案

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

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

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

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

要查看的注册表项是

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

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

这就是全部。

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

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

微软的方式是这样的:

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

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

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

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

此处介绍了检测.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

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

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

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

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

%systemroot%\Microsoft.NET\Framework

然后搜索:

Mscorlib.dll

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

奇怪的是,我写了一些代码在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;
}

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

There is an official Microsoft answer to this question at the knowledge base article [How to determine which versions and service pack levels of the Microsoft .NET Framework are installed][2]

文章ID: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版本。 ...为什么微软的官方回答如此误导?