如何在Delphi中检查操作系统版本?是Windows 7还是Server 2008 R2?

11

我过去经常通过系统的主/次构建版本号来检查Windows的版本。奇怪的是,Windows 7和Server 2008 R2返回相同的主/次版本号组合。

在命令提示符中键入ver确认这一点。


试图寻找功能而不是版本号。大多数Windows版本之间的兼容性错误都是因为有人依赖于特定的版本号。 - idstam
5个回答

23

这段代码可以正确检测许多Windows产品版本,包括Windows XP、Windows 7(家庭版、专业版)、Windows Server 2003和Windows Server 2008,并包含可识别Windows 8和Windows Server 2012的代码。它可以在Delphi 2007、XE2和XE3上编译,并已在WinXP Professional(SP2和SP3)、Windows 7 Pro 64位以及Windows Server 2003/2008(32位2003、64位2008)上进行了测试。它应该也能在其他许多系统上运行,但我没有这些系统来测试。

这段代码提供了D2007下缺失于Windows单元中的定义,动态加载后期Windows版本中可用的函数,并在可用时使用它们(但如果找不到这些函数,它也不会失败)。它还包含了一些相当过时的检测Win95/ME/NT4的方法;由于它们是从此代码之前的版本遗留下来的,因此可以根据您的需要使用它们(或删除它们)。

unit GetWinVersionInfo platform;

interface

uses
  Windows;

{$IF RTLVersion < 18}
{$MESSAGE Warn 'Not tested on Delphi versions before 2007!'}
{$IFEND}


function GetOSInfo: string;

var
  GetProductInfo: function (dwOSMajorVersion, dwOSMinorVersion,
                            dwSpMajorVersion, dwSpMinorVersion: DWORD;
                            var pdwReturnedProductType: DWORD): BOOL stdcall = nil;
var
  GetNativeSystemInfo: procedure(var SysInfo: TSystemInfo); stdcall = nil;

implementation

uses Registry, SysUtils;

{$IF RTLVersion < 19}

// Only used for pre-unicode versions of Delphi. Provides some definitions that
// Windows.pas doesn't provide in earlier versions of Delphi (most likely because
// they didn't exist them.
//
// No support for the W versions of the API definitions

type
  _OSVERSIONINFOEX = record
    dwOSVersionInfoSize : DWORD;
    dwMajorVersion      : DWORD;
    dwMinorVersion      : DWORD;
    dwBuildNumber       : DWORD;
    dwPlatformId        : DWORD;
    szCSDVersion        : array[0..127] of AnsiChar;
    wServicePackMajor   : WORD;
    wServicePackMinor   : WORD;
    wSuiteMask          : WORD;
    wProductType        : BYTE;
    wReserved           : BYTE;
  end;
  TOSVERSIONINFOEX = _OSVERSIONINFOEX;

const
  VER_NT_WORKSTATION    :Integer = 1;
  VER_SUITE_ENTERPRISE  :Integer = 2;
  VER_NT_SERVER         :Integer = 3;
  VER_SUITE_DATACENTER  :Integer = 128;
  VER_SUITE_PERSONAL    :Integer = 512;

const
  PRODUCT_UNDEFINED                           = $00000000;
  PRODUCT_ULTIMATE                            = $00000001;
  PRODUCT_HOME_BASIC                          = $00000002;
  PRODUCT_HOME_PREMIUM                        = $00000003;
  PRODUCT_ENTERPRISE                          = $00000004;
  PRODUCT_HOME_BASIC_N                        = $00000005;
  PRODUCT_BUSINESS                            = $00000006;  { Business }
  PRODUCT_STANDARD_SERVER                     = $00000007;
  PRODUCT_DATACENTER_SERVER                   = $00000008;
  PRODUCT_SMALLBUSINESS_SERVER                = $00000009;
  PRODUCT_ENTERPRISE_SERVER                   = $0000000A;
  PRODUCT_STARTER                             = $0000000B;
  PRODUCT_DATACENTER_SERVER_CORE              = $0000000C;
  PRODUCT_STANDARD_SERVER_CORE                = $0000000D;
  PRODUCT_ENTERPRISE_SERVER_CORE              = $0000000E;
  PRODUCT_ENTERPRISE_SERVER_IA64              = $0000000F;
  PRODUCT_BUSINESS_N                          = $00000010;
  PRODUCT_WEB_SERVER                          = $00000011;
  PRODUCT_CLUSTER_SERVER                      = $00000012;
  PRODUCT_HOME_SERVER                         = $00000013;
  PRODUCT_STORAGE_EXPRESS_SERVER              = $00000014;
  PRODUCT_STORAGE_STANDARD_SERVER             = $00000015;
  PRODUCT_STORAGE_WORKGROUP_SERVER            = $00000016;
  PRODUCT_STORAGE_ENTERPRISE_SERVER           = $00000017;
  PRODUCT_SERVER_FOR_SMALLBUSINESS            = $00000018;
  PRODUCT_SMALLBUSINESS_SERVER_PREMIUM        = $00000019;
  PRODUCT_HOME_PREMIUM_N                      = $0000001A;
  PRODUCT_ENTERPRISE_N                        = $0000001B;
  PRODUCT_ULTIMATE_N                          = $0000001C;
  PRODUCT_WEB_SERVER_CORE                     = $0000001D;
  PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT    = $0000001E;
  PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY      = $0000001F;
  PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING     = $00000020;
  PRODUCT_SERVER_FOUNDATION                   = $00000021;
  PRODUCT_HOME_PREMIUM_SERVER                 = $00000022;
  PRODUCT_SERVER_FOR_SMALLBUSINESS_V          = $00000023;
  PRODUCT_STANDARD_SERVER_V                   = $00000024;
  PRODUCT_DATACENTER_SERVER_V                 = $00000025;
  PRODUCT_ENTERPRISE_SERVER_V                 = $00000026;
  PRODUCT_DATACENTER_SERVER_CORE_V            = $00000027;
  PRODUCT_STANDARD_SERVER_CORE_V              = $00000028;
  PRODUCT_ENTERPRISE_SERVER_CORE_V            = $00000029;
  PRODUCT_HYPERV                              = $0000002A;
  PRODUCT_STORAGE_EXPRESS_SERVER_CORE         = $0000002B;
  PRODUCT_STORAGE_STANDARD_SERVER_CORE        = $0000002C;
  PRODUCT_STORAGE_WORKGROUP_SERVER_CORE       = $0000002D;
  PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE      = $0000002E;
  PRODUCT_STARTER_N                           = $0000002F;
  PRODUCT_PROFESSIONAL                        = $00000030;
  PRODUCT_PROFESSIONAL_N                      = $00000031;
  PRODUCT_SB_SOLUTION_SERVER                  = $00000032;
  PRODUCT_SERVER_FOR_SB_SOLUTIONS             = $00000033;
  PRODUCT_STANDARD_SERVER_SOLUTIONS           = $00000034;
  PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE      = $00000035;
  PRODUCT_SB_SOLUTION_SERVER_EM               = $00000036;
  PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM          = $00000037;
  PRODUCT_SOLUTION_EMBEDDEDSERVER             = $00000038;
  PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE        = $00000039;
  PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE   = $0000003F;
  PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT       = $0000003B;
  PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL       = $0000003C;
  PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC    = $0000003D;
  PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC    = $0000003E;
  PRODUCT_CLUSTER_SERVER_V                    = $00000040;
  PRODUCT_EMBEDDED                            = $00000041;
  PRODUCT_STARTER_E                           = $00000042;
  PRODUCT_HOME_BASIC_E                        = $00000043;
  PRODUCT_HOME_PREMIUM_E                      = $00000044;
  PRODUCT_PROFESSIONAL_E                      = $00000045;
  PRODUCT_ENTERPRISE_E                        = $00000046;
  PRODUCT_ULTIMATE_E                          = $00000047;
  PRODUCT_UNLICENSED                          = $ABCDABCD;

const
  PROCESSOR_ARCHITECTURE_INTEL            = 0;
  PROCESSOR_ARCHITECTURE_AMD64            = 9;
  SM_MEDIACENTER                          = 87;
  SM_SERVERR2                             = 89; {GetSystemMetrics for Win Server 2K3}

function GetVersionEx(var lpVersionInformation: TOSVersionInfo): BOOL; stdcall; overload;
  external kernel32 name 'GetVersionExA';
function GetVersionEx(var lpVersionInformationEx: TOSVERSIONINFOEX): BOOL; stdcall; overload;
  external kernel32 name 'GetVersionExA';

{$IFEND}

  // Not in the Windows.pas unit as of XE3
const
  PRODUCT_PROFESSIONAL_WMC                    = $00000067; {Professional with Media Center}

function GetOSInfo: string;
var
  NTBres, BRes: Boolean;
  OSVI: TOSVERSIONINFO;
  OSVI_NT: TOSVERSIONINFOEX;
  tmpStr: string;
  pdwReturnedProductType : DWORD;
  SI: TSystemInfo;
begin
  Result := 'Error';
  NTBRes := FALSE;
  try
    OSVI_NT.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFOEX);
    NTBRes := GetVersionEx(OSVI_NT);
    OSVI.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
    BRes := GetVersionEx(OSVI);
  except
    OSVI.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
    BRes := GetVersionEx(OSVI);
  end;
  if (not BRes) and (not NTBres) then
    Exit;
  Move( OSVI, OSVI_NT, SizeOf(TOSVersionInfo) );

  if Assigned(GetNativeSystemInfo) then
    GetNativeSystemInfo(SI)
  else
    GetSystemInfo(SI);

  case OSVI_NT.dwPlatformId of
     VER_PLATFORM_WIN32_NT:
       begin
         if OSVI_NT.dwMajorVersion <= 4 then
           Result := 'Windows NT ';
         if (OSVI_NT.dwMajorVersion = 5) then
         begin
           case OSVI_NT.dwMinorVersion of
             0: Result := 'Windows 2000 ';
             1: begin
                  Result := 'Windows XP ';
                  if (GetSystemMetrics(SM_MEDIACENTER) <> 0) then
                    Result := Result + 'Media Center';
                end;
             2: begin
                 if (OSVI_NT.wProductType = VER_NT_WORKSTATION) and
                    (SI.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64) then
                   Result := 'Windows XP Professional x64 '
                 else
                 begin
                   if GetSystemMetrics(SM_SERVERR2) <> 0 then
                     Result := 'Windows Server 2003 R2'
                   else
                     Result := 'Windows Server 2003 ';
                end;
             end;
           end;
         end;
         if (OSVI_NT.dwMajorVersion = 6) then
         begin
           case OSVI_NT.dwMinorVersion of
             0: begin
                  if OSVI_NT.wProductType = VER_NT_WORKSTATION then
                    Result := 'Windows Vista '
                  else
                   Result := 'Windows Server 2008 ';
                 end;
             1:  begin
                   if OSVI_NT.wProductType = VER_NT_WORKSTATION then
                     Result := 'Windows 7 '
                   else
                     Result := 'Windows Server 2008 R2 ';
                 end;
             2:  begin
                   if OSVI_NT.wProductType = VER_NT_WORKSTATION then
                     Result := 'Windows 8 '
                   else
                     Result := 'Windows Server 2012 ';
                 end;
           else
             Result := 'Unknown Windows version ';
           end;

           if Assigned(GetProductInfo) then
           begin
             GetProductInfo(OSVI_NT.dwMajorVersion,
                            OSVI_NT.dwMinorVersion,
                            0,
                            0,
                            pdwReturnedProductType);
             case pdwReturnedProductType of
               PRODUCT_PROFESSIONAL,
               PRODUCT_PROFESSIONAL_N:
                 tmpStr := 'Professional';
               PRODUCT_PROFESSIONAL_WMC:
                 tmpStr := 'Professional with Media Center';
               PRODUCT_BUSINESS,
               PRODUCT_BUSINESS_N:
                 tmpStr := 'Business Edition';
               PRODUCT_CLUSTER_SERVER:
                 tmpStr := 'Cluster Server Edition';
               PRODUCT_DATACENTER_SERVER:
                 tmpStr := 'Server Datacenter Edition (full installation)';
               PRODUCT_DATACENTER_SERVER_CORE:
                 tmpStr := 'Server Datacenter Edition (core installation)';
               PRODUCT_ENTERPRISE,
               PRODUCT_ENTERPRISE_N:
                 tmpStr := 'Enterprise Edition';
               PRODUCT_ENTERPRISE_SERVER:
                 tmpStr := 'Server Enterprise Edition (full installation)';
               PRODUCT_ENTERPRISE_SERVER_CORE:
                 tmpStr := 'Server Enterprise Edition (core installation)';
               PRODUCT_ENTERPRISE_SERVER_IA64:
                 tmpStr := 'Server Enterprise Edition for Itanium-based Systems';
               PRODUCT_HOME_BASIC,
               PRODUCT_HOME_BASIC_N:
                 tmpStr := 'Home Basic Edition';
               PRODUCT_HOME_PREMIUM,
               PRODUCT_HOME_PREMIUM_N:
                 tmpStr := 'Home Premium Edition';
               PRODUCT_HOME_PREMIUM_SERVER:
                 tmpStr := 'Home Premium Server Edition';
               PRODUCT_HOME_SERVER:
                 tmpStr := 'Home Server Edition';
               PRODUCT_HYPERV:
                 tmpStr := 'Hyper-V Server Edition';
               PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
                 tmpStr := 'Windows Essential Business Server Management Server Edition';
               PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
                 tmpStr := 'Windows Essential Business Server Security Server Edition';
               PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
                 tmpStr := 'Windows Essential Business Server Messaging Server Edition';
               PRODUCT_SERVER_FOR_SMALLBUSINESS:
                 tmpStr := 'Server for Small Business Edition';
               PRODUCT_SERVER_FOUNDATION:
                 tmpStr := 'Server Foundation';
               PRODUCT_SMALLBUSINESS_SERVER:
                 tmpStr := 'Small Business Server';
               PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
                 tmpStr := 'Small Business Server Premium Edition';
               PRODUCT_STANDARD_SERVER:
                 tmpStr := 'Server Standard Edition (full installation)';
               PRODUCT_STANDARD_SERVER_CORE:
                 tmpStr := 'Server Standard Edition (core installation)';
               PRODUCT_STARTER:
                 tmpStr := 'Starter Edition';
               PRODUCT_STORAGE_ENTERPRISE_SERVER:
                 tmpStr := 'Storage Server Enterprise Edition';
               PRODUCT_STORAGE_EXPRESS_SERVER:
                 tmpStr := 'Storage Server Express Edition';
               PRODUCT_STORAGE_STANDARD_SERVER:
                 tmpStr := 'Storage Server Standard Edition';
               PRODUCT_STORAGE_WORKGROUP_SERVER:
                 tmpStr := 'Storage Server Workgroup Edition';
               PRODUCT_UNDEFINED:
                 tmpStr := 'An unknown product';
               PRODUCT_ULTIMATE,
               PRODUCT_ULTIMATE_N:
                 tmpStr := 'Ultimate Edition';
               PRODUCT_WEB_SERVER:
                 tmpStr := 'Web Server Edition';
               PRODUCT_WEB_SERVER_CORE:
                 tmpStr := 'Web Server Edition (core installation)';
               PRODUCT_UNLICENSED:
                 tmpStr := 'Unlicensed product'
             else
               tmpStr := '';
             end;{ pdwReturnedProductType }
             Result := Result + tmpStr;
             NTBRes := FALSE;
           end;{ GetProductInfo<>NIL }
         end;{ Vista }

         if OSVI_NT.dwMajorVersion >= 6 then
         begin
           if (SI.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64) then
             Result := Result + ' 64-bit'
           else if (SI.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL) then
             Result := Result + ' 32-bit';
         end;

         if NTBres then
         begin
           if OSVI_NT.wProductType = VER_NT_WORKSTATION then
           begin
             case OSVI_NT.wSuiteMask of
               512: Result := Result + 'Personal';
               768: Result := Result + 'Home Premium';
             else
               Result := Result + 'Professional';
             end;
           end
           else if OSVI_NT.wProductType = VER_NT_SERVER then
           begin
             if OSVI_NT.wSuiteMask = VER_SUITE_DATACENTER then
               Result := Result + 'DataCenter Server'
             else if OSVI_NT.wSuiteMask = VER_SUITE_ENTERPRISE then
               Result :=  Result + 'Advanced Server'
             else
               Result := Result + 'Server';
           end{ wProductType=VER_NT_WORKSTATION }
           else
           begin
             with TRegistry.Create do
               try
                 RootKey := HKEY_LOCAL_MACHINE;
                 if OpenKeyReadOnly('SYSTEM\CurrentControlSet\' +
                                    'Control\ProductOptions') then
                   try
                     tmpStr := UpperCase(ReadString('ProductType'));
                     if tmpStr = 'WINNT' then
                       Result := Result + 'Workstation';
                     if tmpStr = 'SERVERNT' then
                       Result := Result + 'Server';
                   finally
                     CloseKey;
                   end;
               finally
                 Free;
               end;
             end;{ wProductType<>VER_NT_WORKSTATION }
           end;{ NTBRes }
         end;{ VER_PLATFORM_WIN32_NT }
     VER_PLATFORM_WIN32_WINDOWS:
       begin
         if (OSVI.dwMajorVersion = 4) and (OSVI.dwMinorVersion = 0) then
         begin
           Result := 'Windows 95 ';
           if OSVI.szCSDVersion[1] = 'C' then
             Result := Result + 'OSR2';
         end;
         if (OSVI.dwMajorVersion = 4) and (OSVI.dwMinorVersion = 10) then
         begin
           Result := 'Windows 98 ';
           if OSVI.szCSDVersion[1] = 'A' then
             Result := Result + 'SE';
         end;
         if (OSVI.dwMajorVersion = 4) and (OSVI.dwMinorVersion = 90) then
           Result := 'Windows Me';
       end;{ VER_PLATFORM_WIN32_WINDOWS }
     VER_PLATFORM_WIN32s:
       Result := 'Microsoft Win32s';
  else
    Result := 'Unknown';
  end;{ OSVI_NT.dwPlatformId }
end;{ GetOSInfo }

initialization
  @GetProductInfo := GetProcAddress(GetModuleHandle('KERNEL32.DLL'),
                                     'GetProductInfo');

  @GetNativeSystemInfo := GetProcAddress(GetModuleHandle('KERNEL32.DLL'),
                                         'GetNativeSystemInfo');

end.

使用示例:

program GetWinVersionInfoTest;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  GetWinVersionInfo;

begin
  WriteLn(GetOSInfo);
  ReadLn;
end.

4
Windows 7 的版本号是 MajorVersion = 6,MinorVersion = 1。 - mmmm
1
@David:我会尽力整理一下。我在2009年发布了这个帖子,直到今天早上看到我的名字并回顾了一下才想起来。我现在正忙于其他事情,但我会在接下来的几天里再次回来进行更多的清理工作。 :-) - Ken White
2
@David:更新后删除了不必要的本地变量,为D2007定义了类型和函数,但不会替换在已经定义它们的更高版本中。并提供了“平台特定”的警告。在D2007 / XE2 / XE3中进行了测试-我现在没有其他版本可用进行测试。仍然可以改进为动态加载GetProductInfo而不是静态加载,但我认为我不会费心去做。 :-) 感谢您的建议。 - Ken White
@Ken White - 我找到了 :) 因为代码被标记为 {$IF RTLVersion < 19}(Delphi的非Unicode版本),而我使用的是Delphi XE,所以我删除了整个代码块。但实际上,在Delphi XE下需要这个代码块。无论如何,还是谢谢。 - Gabriel
1
@kobik:修复了正确性问题。代码中没有使用返回值,所以除了声明之外没有改变任何内容。感谢您指出这一点。 - Ken White
显示剩余12条评论

9

GetVersionEx。版本号及其关联版本的图表在这里。请注意,2008 R2和Windows 7之间的产品类型是不同的。


4
我喜欢使用JCL(Jedi Class Library),它维护一个枚举类型并使用GetVersionEx等其他内容,将每个主要的发行/打包操作系统配置和产品类型(如Windows Server 2008 R2、XP、Win7等)解码为简单的枚举类型。 - Warren P

2

它没有提到Windows 7及以上版本! - John Spaz
不,它并不是完整的答案 - 但它是一个很好的起点。请参考Bruce McGee的图表以获取您需要的额外信息。 - JosephStyons

1

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接