我想确定我的程序是否在某个版本的 Windows Server 上运行。显然, System.Environment 不包含有关 Windows 是服务器版本这一事实的信息(在 操作系统版本对象).

我知道我可以使用 SystemInformation.TerminalServerSession 检查我的程序是否正在远程桌面上运行(另请参阅 这个问题),但如果用户只是远程访问普通客户端 Windows 计算机,情况也是如此。

那么是否有一种受支持的方法来确定代码是在服务器上还是在客户端计算机上运行?如果需要的话我不介意使用 P/Invoke。

笔记:我不想寻找 "Server" 产品名称中的字符串,因为由于本地化的原因,这可能无法在某些系统上运行。

有帮助吗?

解决方案

多亏了尼克的回答提供的指示,我终于找到了我想要的东西。功能 ISO(OS_ANYSERVER) 确实做我需要的。这是适用于任何OS版本的示例代码(包括前Vista,因为我们导入 IsOS 序数功能 shlwapi.dll):

class OS
{
    public static bool IsWindowsServer()
    {
        return OS.IsOS (OS.OS_ANYSERVER);
    }

    const int OS_ANYSERVER = 29;

    [DllImport("shlwapi.dll", SetLastError=true, EntryPoint="#437")]
    private static extern bool IsOS(int os);
}

其他提示

您可以P/调用以下Win32功能:

GetProductinfo 对于Vista/Windows Server 2008+
getVersionex 对于Windows 2000+

BJ Rollison有一个 好帖子示例代码 关于这一点在他的博客上。

IsWindowsServer 是一个 排队 函数于 VersionHelpers.h.

您可以在计算机上找到并读取该头文件。它使用API​​函数 VerifyVersionInfoW.

没有功能 IswindowsServerkernel32.dll.

应该在assembly kernel32.dll中的winapi的versionHelpers.h标头文件中定义了一组“版本助手函数”。根据文档,应适用于您的案件的一个是Iswindowsserver(void)。描述在这里:

http://msdn.microsoft.com/en-us/library/windows/desktop/dn424963%28v=vs.85%29.aspx

在C#中,代码会喜欢此(未经测试):

using System.Runtime.InteropServices;

public static class MyClass
{
    [DllImport("Kernel32.dll")]
    public static extern Boolean IsWindowsServer();
}

然后,消费代码将只是:

bool is_it_a_server = MyClass.IsWindowsServer();

我从来没有使用过这些功能,所以让我知道它是如何工作的...

我遇到了同样的问题,尽管脚本有脚本。

我发现了这个价值;我正在使用WMI查询它:

https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx
Win32_OperatingSystem
ProductType
    Data type: uint32
    Access type: Read-only
    Additional system information.
    Work Station (1)
    Domain Controller (2)
    Server (3)

我对以下操作系统版本进行了测试:

  • Windows XP Professional SP3
  • Windows 7企业
  • Windows 8.1 Pro
  • Windows 8.1企业
  • Windows 10 Pro 10.0.16299
  • Windows Server 2003 R2标准版
  • Windows Server 2003 R2标准版X64
  • Windows Server 2008 R2标准
  • Windows Server 2012数据中心
  • Windows Server 2012 R2数据中心

在下面找到我的示例批处理文件。

卢卡斯。

for /f "tokens=2 delims==" %%a in ( 'wmic.exe os get producttype /value' ) do (
    set PRODUCT_TYPE=%%a
)
if %PRODUCT_TYPE%==1 set PRODUCT_TYPE=Workstation
if %PRODUCT_TYPE%==2 set PRODUCT_TYPE=DomainController
if %PRODUCT_TYPE%==3 set PRODUCT_TYPE=Server
echo %COMPUTERNAME%: %PRODUCT_TYPE%

您可以在C#中轻松执行此操作:

using Microsoft.Management.Infrastructure;
...
string Namespace = @"root\cimv2";
string className = "Win32_OperatingSystem";

CimInstance operatingSystem = new CimInstance(className, Namespace);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top