DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: kevin20240329
今日帖子: 43
在线用户: 27
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/9/21 21:56:04
标题:
求能准确识别操作系统产品版本的DELPHI 代码~ 浏览:2362
加入我的收藏
楼主: 新的XE有TOSVersion.ToString 这个函数可以直接显示出完整的操作系统版本号和SP号。还有是多少位的系统。但是有个缺陷就是不能显示是专业版,还是家庭版,还是旗舰版。。查找了一下百度好像没有发现相关的资料。没头绪了!.在Winapi.Windows.pas 文件里发现有
//
// Product types
// This list grows with each OS release.
//
// There is no ordering of values to ensure callers
// do an equality test i.e. greater-than and less-than
// comparisons are not useful.
//
// NOTE: Values in this list should never be deleted.
//       When a product-type 'X' gets dropped from a
//       OS release onwards, the value of 'X' continues
//       to be used in the mapping table of GetProductInfo.
//

  PRODUCT_UNDEFINED          = $00000000;
  {$EXTERNALSYM PRODUCT_UNDEFINED}

  PRODUCT_ULTIMATE          = $00000001;
  {$EXTERNALSYM PRODUCT_ULTIMATE}
  PRODUCT_HOME_BASIC          = $00000002;
  {$EXTERNALSYM PRODUCT_HOME_BASIC}
  PRODUCT_HOME_PREMIUM          = $00000003;
  {$EXTERNALSYM PRODUCT_HOME_PREMIUM}
  PRODUCT_ENTERPRISE          = $00000004;
  {$EXTERNALSYM PRODUCT_ENTERPRISE}
  PRODUCT_HOME_BASIC_N          = $00000005;
  {$EXTERNALSYM PRODUCT_HOME_BASIC_N}
  PRODUCT_BUSINESS          = $00000006;
  {$EXTERNALSYM PRODUCT_BUSINESS}

但是菜鸟一枚,不知道 怎么调用。求高手指点 ~
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/9/21 23:03:19
1楼: https://docs.microsoft.com/zh-cn/windows/desktop/api/winnt/ns-winnt-_osversioninfoexa
----------------------------------------------
--
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/9/21 23:28:29
2楼: 楼上大哥提供的这个只能查看版本号,不能详细到专业版和旗舰版区分。
我找到另外一个函数。GetProductInfo  这个好像可以。自己写了一下。但是好像判断还是不准确。
procedure TForm1.Button20Click(Sender: TObject);
var
  rpt: cardinal;
begin
  if GetProductInfo(6, 1, 0, 0, &rpt) then
    ShowMessage(IntToStr(rpt));
end;

WIN7和2008R2 都是6.1版本号的。但是上面的返回码并不正确。
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/9/21 23:43:44
3楼: 关键字都告诉你了,msdn里到处都是关联信息。。。
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/9/22 8:13:18
4楼: 人家 4 个输入参数,而且 TOSVersion 都有,你居然懒到写死了?
不过 这个函数也就是 WIN10 返回值比较准确点。
任何 SERVER 版,返回都乱七八糟的。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/9/22 22:00:39
5楼: 我有C++的代码,一直觉得用处不大,所以没转成Delphi的。
此帖子包含附件:iamdream_201892222039.zip 大小:29.1K
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/9/22 22:05:50
6楼: 其实就是调用kernel32.dll中的GetProductInfo,或者简单地查询注册表,但不同版本的操作系统可能有些不同,你可查看 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion下的ProductName等键值,详情可参考我的博客文章:http://dreamisx.blog.163.com/blog/static/1150048392012898257606/。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/9/22 22:12:54
7楼: 你需要根据GetProductInfo的最后一个参数返回的值来判断,并且在windows8.1开始的版本用GetVersionEx得到的结果已经不准确了,应该用RtlGetVersion这个函数,然后根据这个函数的结果再调用GetProductInfo来获取产品版本。
所以,还是建议你读注册表吧。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/9/23 1:01:27
8楼: 楼上的,有必要搞那么麻烦?直接用内置变量不就结了么?
win32majorversion已经帮你取好了,直接用不就完了么?

另外就是,GetProductInfo函数之所以这么乱,是因为windows版本本身就乱,有兴趣的去看看windows从95开始到10,一共有多少个子版本就清楚了。
----------------------------------------------
--
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2018/9/23 8:57:02
9楼: 有试过 TjclSysInfo 吗?
----------------------------------------------
UniKeeper V10.40 -- 您最贴心的个人数据管理助手
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/9/23 12:46:54
10楼: 呃,楼主想要知道产品的具体版本,光有win32majorversion根本不行,再说了,GetVersionEx在新版Windows(>=8.1)下已经不准了。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/9/23 17:26:17
11楼: 直接用win32xxx这几个变量就可以,vcl内部已经处理过了。
实在想判断出很详细的信息,可以跳过getversionex这步。
----------------------------------------------
--
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2018/9/25 9:02:07
12楼: function GetWindowsVersion: string;
var
  OsVerInfo: TOSVersionInfoEx;
  ExVerExist: Boolean;
  ProductType: string;
begin
  Result := 'Microsoft Windows';
  ExVerExist := True;
  OsVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfoEx);
  if not GetVersionEx(POSVersionInfo(@OsVerInfo)^) then
  begin
    OsVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
    GetVersionEx(POSVersionInfo(@OsVerInfo)^);
    ExVerExist := False;
  end;
  with OsVerInfo do
  begin
    case dwPlatformId of
      VER_PLATFORM_WIN32s:
        Result := Result + Format(' %d.%d', [dwMajorVersion, dwMinorVersion]);
      VER_PLATFORM_WIN32_WINDOWS: { Windows 9x/ME }
        begin
          if (dwMajorVersion = 4) and (dwMinorVersion = 0) then
          begin
          Result := Result + ' 95';
          if szCSDVersion[1] in ['B', 'C'] then
          Result := Result + ' OSR2';
          end
          else if (dwMajorVersion = 4) and (dwMinorVersion = 10) then
          begin
          Result := Result + ' 98';
          if (OsVerInfo.szCSDVersion[1] = 'A') then
          Result := Result + ' Second Edition';
          end
          else if (dwMajorVersion = 4) and (dwMinorVersion = 90) then
          Result := Result + ' Millenium Edition';
        end;
      VER_PLATFORM_WIN32_NT: { Windows NT/2000 }
        begin
          case dwMajorVersion of
          3, 4:
          Result := Result + Format(' NT %d.%d', [dwMajorVersion, dwMinorVersion]);
          5:
          begin
          if dwMinorVersion = 0 then
          Result := Result + ' 2000'
          else if dwMinorVersion = 1 then
          Result := Result + ' XP'
          else if dwMinorVersion = 2 then
          Result := Result + ' 2003 Server';
          end;
          // 6: Windows Server "Longhorn" ,Windows Vista
          end;
          if ExVerExist then
          begin
          if wProductType = VER_NT_WORKSTATION then
          begin
          if dwMajorVersion = 4 then
          Result := Result + ' Workstation'
          else if wSuiteMask and VER_SUITE_PERSONAL <> 0 then
          Result := Result + ' Home Edition'
          else if dwMajorVersion = 6 then
          Result := Result + ' Vista'
          else
          Result := Result + ' Professional';
          end
          else if wProductType = VER_NT_SERVER then
          begin
          if (dwMajorVersion = 5) and (dwMinorVersion = 2) then
          begin
          if wSuiteMask and VER_SUITE_DATACENTER <> 0 then
          Result := Result + ' Datacenter Edition'
          else if wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
          Result := Result + ' Enterprise Edition'
          else if wSuiteMask and VER_SUITE_BLADE <> 0 then
          Result := Result + ' Web Edition'
          else if wSuiteMask and VER_SUITE_STORAGE_SERVER <> 0 then
          Result := Result + ' R2'
          else
          Result := Result + ' Standard Edition';
          end
          else if (dwMajorVersion = 5) and (dwMinorVersion = 0) then
          begin
          if wSuiteMask and VER_SUITE_DATACENTER <> 0 then
          Result := Result + ' Datacenter Server'
          else if wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
          Result := Result + ' Advanced Server'
          else
          Result := Result + ' Server'
          end
          else if (dwMajorVersion = 6) and (dwMinorVersion = 0) then
          begin
          if wSuiteMask and VER_SUITE_DATACENTER <> 0 then
          Result := Result + 'Server "Longhorn" Datacenter Edition'
          else if wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
          Result := Result + 'Server "Longhorn" Enterprise Edition'
          end
          else
          begin
          Result := Result + ' Server';
          if wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
          Result := Result + ' Enterprise Edition';
          end;
          end;
          end
          else
          begin
          with TRegistry.Create do
          begin
          try
          RootKey := HKEY_LOCAL_MACHINE;
          if OpenKey('\SYSTEM\CurrentControlSet\Control\ProductOptions', False) then
          begin
          if ValueExists('ProductType') then
          begin
          ProductType := ReadString('ProductType');
          if SameText(ProductType, 'WinNT') then
          Result := Result + ' Workstation'
          else if SameText(ProductType, 'LanManNT') then
          Result := Result + ' Server'
          else if SameText(ProductType, 'ServerNT') then
          Result := Result + ' Advance Server';
          end;
          CloseKey;
          end;
          finally
          Free;
          end;
          end;
          end;
          Result := Result + ' ' + szCSDVersion;
          if (dwMajorVersion = 4) and SameText(szCSDVersion, 'Service Pack 6') then
          begin
          with TRegistry.Create do
          begin
          try
          RootKey := HKEY_LOCAL_MACHINE;
          if OpenKey('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix\Q246009', False) then
          begin
          Result := Result + 'a';
          CloseKey;
          end;
          finally
          Free;
          end;
          end;
          end;
        end;
    end;
    Result := Format(Result + ' (%d.%d Build %d)', [
      dwMajorVersion,
      dwMinorVersion,
      dwBuildNumber and $FFFF]);
  end
end;
此帖子包含附件:
PNG 图像
大小:34.6K
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 wufan314 (真的吗) ★☆☆☆☆ -
普通会员
2024/1/11 16:39:04
13楼: @earthsbest:你这个还需要引用什么单元吗?D7下编译通不过。

下面这个通过FWMIService查询系统表Win32_OperatingSystem, 该方法可以正常读取系统版本WIN8(6.2), WIN81(6.3), WIN10(10)

function GetWMIProperty(WMIType, WMIProperty: string): string;
var
  Wmi, Objs, Obj: OleVariant;
  Enum: IEnumVariant;
  C: Cardinal;
begin
  Wmi:= CreateOleObject('WbemScripting.SWbemLocator');
  Objs := Wmi.ConnectServer('.','root/cimv2').ExecQuery('Select * from Win32_' + WMIType);
  Enum := IEnumVariant(IUnknown(Objs._NewEnum));
  Enum.Reset;
  Enum.Next(1, Obj, C);
  Obj := Obj.Properties_.Item(WMIProperty, 0).Value;
  Result := Obj;
end;
Showmessage(GetWMIProperty('OperatingSystem', 'Version'));
----------------------------------------------
-
作者:
男 adsoft (adsoft) ★☆☆☆☆ -
普通会员
2024/1/11 19:23:54
14楼: https://github.com/ddablib/sysinfo
----------------------------------------------
-
作者:
男 xuchuantao (暗黑天使) ★☆☆☆☆ -
普通会员
2024/1/11 21:11:32
15楼: unit WinVerUtils;

{$IF not(defined(WINDOWS) or defined(MSWINDOWS))}
{$MESSAGE FATAL 'Unsupported operating system.'}
{$IFEND}
{$IFDEF FPC}
{$MODE ObjFPC}
{$ENDIF}
{$H+}

interface

uses
  SysUtils, Windows;

type
  TOSVersionInfo = record
    Name: WideString;
    MajorVersion: DWORD;
    MinorVersion: DWORD;
    BuildNumber: DWORD;
    PlatformId: DWORD;
    SuiteMask: WORD;
    ServicePackMajor: WORD;
    ServicePackMinor: WORD;
    ProductType: BYTE;
    ProductName: WideString;
    ReleaseId: WideString;
    DisplayVersion: WideString;
    szCSDVersion: WideString;
    SystemInfo: TSystemInfo;
  end;

var
  OSVersionInfo: TOSVersionInfo;

implementation

uses Registry;

var
  RtlGetVersion: function(var RTL_OSVERSIONINFOEXW): LongInt; stdcall;

function GetWindowsVersion: TOSVersionInfo;
const
  MAJOR_VERSION_MASK = $0F;
  UnknownOSVersionInfo: TOSVersionInfo = (Name: 'Unknown'; MajorVersion: 0;
    MinorVersion: 0; BuildNumber: 0; ProductType: VER_NT_WORKSTATION);
  WindowsServerOSVersionInfoArray: Array [0 .. 9] of TOSVersionInfo =
    ((Name: 'Windows Server 2003'; MajorVersion: 5; MinorVersion: 2;
    BuildNumber: 3790; ProductType: VER_NT_SERVER),
    (Name: 'Windows Server 2003 R2'; MajorVersion: 5; MinorVersion: 2;
    BuildNumber: 3790; ProductType: VER_NT_SERVER),
    (Name: 'Windows Home Server'; MajorVersion: 5; MinorVersion: 2;
    BuildNumber: 4500; ProductType: VER_NT_SERVER),
    (Name: 'Windows Server 2008'; MajorVersion: 6; MinorVersion: 0;
    BuildNumber: 6001; ProductType: VER_NT_SERVER),
    (Name: 'Windows Server 2008 Service Pack 2'; MajorVersion: 6;
    MinorVersion: 0; BuildNumber: 6002; ProductType: VER_NT_SERVER),
    (Name: 'Windows Server 2008, Service Pack 2, Rollup KB4489887';
    MajorVersion: 6; MinorVersion: 0; BuildNumber: 6003;
    ProductType: VER_NT_SERVER), (Name: 'Windows Server 2008 R2';
    MajorVersion: 6; MinorVersion: 1; BuildNumber: 7600;
    ProductType: VER_NT_SERVER), (Name: 'Windows Server 2008 R2 Service Pack 1';
    MajorVersion: 6; MinorVersion: 1; BuildNumber: 7601;
    ProductType: VER_NT_SERVER), (Name: 'Windows Home Server 2011';
    MajorVersion: 6; MinorVersion: 1; BuildNumber: 8400;
    ProductType: VER_NT_SERVER), (Name: 'Windows Server 2022'; MajorVersion: 10;
    MinorVersion: 0; BuildNumber: 20348; ProductType: VER_NT_SERVER));
  WORKSTATIONOSVersionInfoArray: Array [0 .. 34] of TOSVersionInfo =
    ((Name: 'Windows NT 3.1'; MajorVersion: 3; MinorVersion: 1;
    BuildNumber: 528; ProductType: VER_NT_WORKSTATION), (Name: 'Windows NT 3.5';
    MajorVersion: 3; MinorVersion: 5; BuildNumber: 807;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows NT 3.51'; MajorVersion: 3;
    MinorVersion: 5; BuildNumber: 1057; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows 95'; MajorVersion: 4; MinorVersion: 0; BuildNumber: 950;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 98'; MajorVersion: 4;
    MinorVersion: 1; BuildNumber: 1998; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows 98 Second Edition'; MajorVersion: 4; MinorVersion: 1;
    BuildNumber: 2222; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows NT 4.0'; MajorVersion: 4; MinorVersion: 0;
    BuildNumber: 1381; ProductType: VER_NT_WORKSTATION), (Name: 'Windows 2000';
    MajorVersion: 5; MinorVersion: 0; BuildNumber: 2195;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows Me'; MajorVersion: 4;
    MinorVersion: 90; BuildNumber: 3000; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows XP'; MajorVersion: 5; MinorVersion: 1; BuildNumber: 2600;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows Vista'; MajorVersion: 6;
    MinorVersion: 0; BuildNumber: 6000; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows Vista Service Pack 1'; MajorVersion: 6; MinorVersion: 0;
    BuildNumber: 6001; ProductType: VER_NT_SERVER),
    (Name: 'Windows Vista Service Pack 2'; MajorVersion: 6; MinorVersion: 0;
    BuildNumber: 6002; ProductType: VER_NT_SERVER), (Name: 'Windows 7';
    MajorVersion: 6; MinorVersion: 1; BuildNumber: 7600;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 7 Service Pack 1';
    MajorVersion: 6; MinorVersion: 1; BuildNumber: 7601;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 8'; MajorVersion: 6;
    MinorVersion: 2; BuildNumber: 9200; ProductType: VER_NT_WORKSTATION),
    (Name: 'Windows 8.1'; MajorVersion: 6; MinorVersion: 3; BuildNumber: 9200;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 8.1 Update 1';
    MajorVersion: 6; MinorVersion: 3; BuildNumber: 9600;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1507';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 10240;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1511';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 10586;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1607';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 14393;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1703';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 15063;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1709';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 16299;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1803';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 17134;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1809';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 17763;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1903';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 18362;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 1909';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 18363;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 2004';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 19041;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 20H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 19042;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 21H1';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 19043;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 21H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 19044;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 10 22H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 19045;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 11 21H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 22000;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 11 22H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 22621;
    ProductType: VER_NT_WORKSTATION), (Name: 'Windows 11 23H2';
    MajorVersion: 10; MinorVersion: 0; BuildNumber: 22631;
    ProductType: VER_NT_WORKSTATION));
var
  I, M: Int64;
  BuildNumber: DWORD;
  Registry: TRegistry;
  OSVersion: RTL_OSVERSIONINFOEXW;
begin
  Result := UnknownOSVersionInfo;
  if GetSystemMetrics(SM_SERVERR2) <> 0 then
  begin
    Result := WindowsServerOSVersionInfoArray[1];
  end
  else
  begin
    if Assigned(RtlGetVersion) then
    begin
      ZeroMemory(@OSVersion, SizeOf(OSVersion));
      OSVersion.dwOSVersionInfoSize := SizeOf(OSVersion);
      if RtlGetVersion(OSVersion) = 0 then
      begin
        BuildNumber := OSVersion.dwBuildNumber;
        case OSVersion.wProductType of
          VER_NT_WORKSTATION:
          begin
          if BuildNumber = 10 then
          begin
          M := 19;
          end
          else
          begin
          M := Low(WORKSTATIONOSVersionInfoArray)
          end;
          for I := M to High(WORKSTATIONOSVersionInfoArray) do
          begin
          if WORKSTATIONOSVersionInfoArray[I].BuildNumber = BuildNumber
          then
          begin
          Result := WORKSTATIONOSVersionInfoArray[I];
          Break;
          end;
          end;
          end;
          VER_NT_SERVER, VER_NT_DOMAIN_CONTROLLER:
          Begin
          if BuildNumber = 10 then
          begin
          M := 9;
          end
          else
          begin
          M := Low(WindowsServerOSVersionInfoArray)
          end;
          for I := M to High(WindowsServerOSVersionInfoArray) do
          begin
          if WindowsServerOSVersionInfoArray[I].BuildNumber = BuildNumber
          then
          begin
          Result := WindowsServerOSVersionInfoArray[I];
          Break;
          end;
          end;
          end;
        end;
        Result.PlatformId := OSVersion.dwPlatformId;
        Result.SuiteMask := OSVersion.wSuiteMask;
        Result.szCSDVersion := OSVersion.szCSDVersion;
        Result.ProductType := OSVersion.wProductType;
        Result.ServicePackMajor := OSVersion.WServicePackMajor;
        Result.ServicePackMinor := OSVersion.WServicePackMinor;
        Registry := TRegistry.Create;
        Registry.RootKey := HKEY_LOCAL_MACHINE;
        if Registry.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion', True)
        then
        begin
          Result.ReleaseId := Registry.ReadString('ReleaseId');
          Result.ProductName := Registry.ReadString('ProductName');
          Result.DisplayVersion := Registry.ReadString('DisplayVersion');
        end;
        Registry.Free;
      end;
    end;
  end;
  Result.SystemInfo.dwOemId := 0;
  GetNativeSystemInfo(Result.SystemInfo);
end;

initialization

@RtlGetVersion := GetProcAddress(GetModuleHandle('ntdll.dll'), 'RtlGetVersion');
OSVersionInfo := GetWindowsVersion;

end.
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ★☆☆☆☆ -
普通会员
2024/1/11 21:12:03
16楼: 之前写的代码,你可以参考一下
----------------------------------------------
按此在新窗口浏览图片
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2024/1/11 22:23:12
17楼: 可以参考 JCL 的 JclSysInfo.pas:

function GetWindowsVersion: TWindowsVersion;
function GetWindowsEdition: TWindowsEdition;
function NtProductType: TNtProductType;
function GetWindowsVersionString: string;
function GetWindowsEditionString: string;
function GetWindowsProductString: string;
function GetWindowsProductName: string;

type
  TWindowsVersion =
   (wvUnknown, wvWin95, wvWin95OSR2, wvWin98, wvWin98SE, wvWinME,
    wvWinNT31, wvWinNT35, wvWinNT351, wvWinNT4, wvWin2000, wvWinXP,
    wvWin2003, wvWinXP64, wvWin2003R2, wvWinVista, wvWinServer2008,
    wvWin7, wvWinServer2008R2, wvWin8, wvWin8RT, wvWinServer2012,
    wvWin81, wvWin81RT, wvWinServer2012R2, wvWin10, wvWinServer2016,
    wvWinServer2019, wvWinServer, wvWin11, wvWinServer2022);
  TWindowsEdition =
   (weUnknown, weWinXPHome, weWinXPPro, weWinXPHomeN, weWinXPProN, weWinXPHomeK,
    weWinXPProK, weWinXPHomeKN, weWinXPProKN, weWinXPStarter, weWinXPMediaCenter,
    weWinXPTablet, weWinVistaStarter, weWinVistaHomeBasic, weWinVistaHomeBasicN,
    weWinVistaHomePremium, weWinVistaBusiness, weWinVistaBusinessN,
    weWinVistaEnterprise, weWinVistaUltimate, weWin7Starter, weWin7HomeBasic,
    weWin7HomePremium, weWin7Professional, weWin7Enterprise, weWin7Ultimate,
    weWin8, weWin8Pro, weWin8Enterprise, weWin8RT, weWin81, weWin81Pro,
    weWin81Enterprise, weWin81RT, weWin10, weWin10Home, weWin10Pro,
    weWin10Enterprise, weWin10Education);
  TNtProductType =
   (ptUnknown, ptWorkStation, ptServer, ptAdvancedServer,
    ptPersonal, ptProfessional, ptDatacenterServer, ptEnterprise, ptWebEdition);
  TProcessorArchitecture =
   (paUnknown, // unknown processor
    pax8632,   // x86 32 bit processors (some P4, Celeron, Athlon and older)
    pax8664,   // x86 64 bit processors (latest P4, Celeron and Athlon64)
    paIA64);   // Itanium processors
----------------------------------------------
-
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2024/1/11 22:46:27
18楼: 调函数再穷举,遇到新的操作系统,还是要改程序。

LZ可以试试,简单的调用命令行
“wmic os get caption”取名字,比如得到:Microsoft Windows 11 Pro
“wmic os get version”取版本号。

Linux下同理:
“at /etc/os-release | grep PRETTY | cut -d '\' -f 2”

调命令行的好处是比如还想看CPU信息一类的,都可以取到。
----------------------------------------------
Bye bye DDRFAN...
作者:
男 bighawk (Hawk) ★☆☆☆☆ -
盒子活跃会员
2024/1/12 11:52:56
19楼: 引用:GetVersionEx在新版Windows(>=8.1)下已经不准了。
其实也不是说不准,只是后续版本的 Windows 增加了机制,可执行文件需要增加一个资源,申明此可执行文件需要用到的 Windows 版本特性。其实就是一个 XML 文件。类似于如下:
    <!-- Windows 10 -->
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
          <!-- Windows 10 -->
          <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
          <!-- Windows 8.1 -->
          <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
          <!-- Windows Vista -->
          <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
          <!-- Windows 7 -->
          <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
          <!-- Windows 8 -->
          <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
        </application>
    </compatibility>
添加了此资源以后,Windows 的相关 API 返回的数据才正确
----------------------------------------------
-
作者:
男 wufan314 (真的吗) ★☆☆☆☆ -
普通会员
2024/1/12 13:42:30
20楼: @bighawk:其实还是操作系统本身的问题,OS就应该自身提供关于版本的函数,就像命令行Ver那种程序调用相应函数OS就按要求报告才对,而不是要程序自己去通过已有的特征去查询甚至分析确定。GetVersionEx在WIN11下报告都是WIN7,版本号给的是6.1,不是不准,而是根本错误了。
----------------------------------------------
-
作者:
男 bighawk (Hawk) ★☆☆☆☆ -
盒子活跃会员
2024/1/12 14:12:10
21楼: 这是 windows 的版本兼容功能的一部分,在初始化应用环境的时候,不需要把较新操作系统的特性全部加载,因为对较为古老的应用来说无用负荷过多,但是对于较新的应用而言,延后加载可能会较大影响用户体验。所以 windows 才使用这个方式来实现兼容,应用自身申明需要使用的操作系统特性和运行的版本环境;对于不采用这种申明方式的应用,windows 可以判定为使用较老 windows 特性的应用程序,所以它较为贴心的为此种应用程序提供较老的 windows 版本号,也从某个方面避免此种应用程序可能发生的崩溃:比如没编写对较高系统版本号的处理代码。这从另一个方面而言也是 windows 的兼容模型的较好体现
----------------------------------------------
-
作者:
男 wufan314 (真的吗) ★☆☆☆☆ -
普通会员
2024/1/12 14:28:38
22楼: 是否报告准确的版本号和兼容性没关系吧?
能否运行和是否提供正确的版本号无关。
----------------------------------------------
-
作者:
男 bighawk (Hawk) ★☆☆☆☆ -
盒子活跃会员
2024/1/12 14:38:21
23楼: 说的很对,受教了。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行738.2813毫秒 RSS