确定程序是不是在 Windows Server 上运行
Posted
技术标签:
【中文标题】确定程序是不是在 Windows Server 上运行【英文标题】:Determining if the program is running on Windows Server确定程序是否在 Windows Server 上运行 【发布时间】:2011-03-09 11:21:47 【问题描述】:我想确定我的程序是否在某个版本的 Windows Server 上运行。显然,System.Environment
不包含有关 Windows 是服务器版本这一事实的信息(OS version object 中没有此类信息)。
我知道我可以使用SystemInformation.TerminalServerSession
来检查我的程序是否在远程桌面上运行(另请参阅this question),但如果用户只是远程访问普通客户端 Windows 机器,这也是正确的。
那么是否有一种受支持的方式来确定代码是在服务器上还是在客户端计算机上运行?如果需要,我不介意使用 P/Invoke。
注意:我不想在产品名称中搜索"Server"
字符串,因为由于本地化,这可能不适用于某些系统。
【问题讨论】:
【参考方案1】:感谢尼克的回答提供的指示,我终于找到了我要找的东西。函数IsOS(OS_ANYSERVER) 正是我所需要的。这是适用于任何操作系统版本的示例代码(包括Vista之前的版本,因为我们从shlwapi.dll
按序号导入IsOS
函数):
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);
【讨论】:
如果 nick 给了您用来获取所需信息的答案,那么您应该接受该答案而不是您自己的答案(此处的信息应在您的问题中进行编辑)。 好吧,Nick 没有提供 IsOS 解决方案。因此,其他读者将我自己的答案标记为已接受的答案似乎更有用。我给尼克投了赞成票。 这是一个很好的答案,感谢您的帮助。另外,当我必须调用外部方法时,我总是使用一个非常好的站点:pinvoke.net 这是 IsOS 方法:pinvoke.net/default.aspx/shlwapi/IsOS.html【参考方案2】:您可以 p/调用以下 Win32 函数:
GetProductInfo 适用于 Vista/Windows Server 2008+GetVersionEx 适用于 Windows 2000+
BJ Rollison 在他的博客上有关于此的 good post 和 sample code。
【讨论】:
感谢您的链接。我终于通过调用 IsOS 解决了这个问题。【参考方案3】:IsWindowsServer
是VersionHelpers.h
中的一个内联函数。
您可以在计算机上找到并读取该头文件。它使用API函数VerifyVersionInfoW
。
kernel32.dll
中没有函数IswindowsServer
。
【讨论】:
【参考方案4】:我遇到了同样的问题,尽管是在脚本中。
我找到了这个值;我正在使用 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 专业版 SP3 Windows 7 企业版 Windows 8.1 专业版 Windows 8.1 企业版 Windows 10 专业版 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);
【讨论】:
【参考方案5】:应该在程序集 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();
我从来没有使用过这些功能,所以请告诉我它是如何工作的......
【讨论】:
当我将 Kernel32.dll 或 Ntdll.dll 用于 DllImport 时,我收到一个错误,即在这些程序集中找不到 IsWindowsServer()。 见 Paul Hoepping 的回答;他解释了为什么在kernel32.dll
中找不到IsWindowsServer
。
此功能不可互操作请务必查看此站点pinvoke.net,这对我每次都有很大帮助。以上是关于确定程序是不是在 Windows Server 上运行的主要内容,如果未能解决你的问题,请参考以下文章
Windows Server 2012 在桌面上显示”我的电脑”图标
windows server 2003 开启telnet 服务