gpt4 book ai didi

delphi - 检查 W10 上的 Windows 版本

转载 作者:行者123 更新时间:2023-12-03 14:41:44 25 4
gpt4 key购买 nike

有谁知道 TOSVersion.Name 在 Windows 10 上是否仍然有效?

我有一个 vcl 应用程序,它有一个表单显示事件,该事件获取操作系统详细信息并使用 SysUtils 中的 TOSVersion 记录将它们显示在 TMemo 框中。

with mmoOSInfo.Lines do 
begin
Clear;
Add(TOSVersion.ToString);
Add('');
Add('Architecture: ' + OSArchitectureToStr(TOSVersion.Architecture));
Add('Platform: ' + OSPlatformToStr(TOSVersion.Platform) +
IntToStr(PlatformFromPointer));
Add('Build: ' + IntToStr(TOSVersion.Build));
Add('Major: ' + IntToStr(TOSVersion.Major));
Add('Minor: ' + IntToStr(TOSVersion.Minor));
Add('Name: ' + TOSVersion.Name);
Add('Service Pack - Major: ' + IntToStr(TOSVersion.ServicePackMajor));
Add('Service Pack - Minor: ' + IntToStr(TOSVersion.ServicePackMinor));
end;

该代码在 XP(是的,我们仍在使用它(羞愧地垂下头))、Vista、Windows 7、Windows 8.1、台式电脑、笔记本电脑和 Surface Pro 上执行没有任何问题,但安装在 Windows 10 上时则不然。

当我使用 paserver 进行调试时,TOSVersion.Name 返回为 := 'Windows 8'。我是否做错了什么,或者我对 TOSVersion 检测 Windows 10 的期望过高?没有异常被触发。在我可以访问的 2 台 Windows 10 计算机中,其中一台迁移路径来自 Windows 8.1,另一台迁移路径来自 Windows 7。

非常感谢

最佳答案

有两件事会阻止您的代码返回正确的版本:

  1. 您使用的 XE8 RTL 早于 Windows 10,因此不了解 Windows 10。
  2. 您的可执行文件本身并不支持 Windows 10,因此 GetVersionEx TOSVersion 所依赖的 ,会谎报版本。

碰巧的是,我相信 XE8 更新 1 将版本检测更改为使用不受此版本谎言约束的 NetWkstaGetInfo。虽然对 NetWkstaGetInfo 的调用确实会泄漏内存,但这可能并不重要,因为它只被调用一次。

与此主题相关的一些链接:

如果您绝对必须向用户报告版本,那么您有多种选择:

  • supportedOS 选项添加到您的 list 中,并包含 Windows 10 的 GUID。这样可以防止 GetVersionEx 撒谎。然后使用 TOSVersion 的修改版本或其他方式来获取版本。
  • 使用 WMI 查询。
  • 调用NetServerGetInfo
  • 调用NetWkstaGetInfo
  • 调用RtlGetVersion

此问题的更多详细信息:How to detect true Windows version?尽管请注意,接受的答案已经过时了。

作为 WMI 方法的示例,您可以使用以下代码:

function OperatingSystemDisplayName: string;

function GetWMIObject(const objectName: string): IDispatch;
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, PChar(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;

function VarToString(const Value: OleVariant): string;
begin
if VarIsStr(Value) then begin
Result := Trim(Value);
end else begin
Result := '';
end;
end;

function FullVersionString(const Item: OleVariant): string;
var
Caption, ServicePack, Version, Architecture: string;
begin
Caption := VarToString(Item.Caption);
ServicePack := VarToString(Item.CSDVersion);
Version := VarToString(Item.Version);
Architecture := ArchitectureDisplayName(SystemArchitecture);
Result := Caption;
if ServicePack <> '' then begin
Result := Result + ' ' + ServicePack;
end;
Result := Result + ', version ' + Version + ', ' + Architecture;
end;

var
objWMIService: OleVariant;
colItems: OleVariant;
Item: OleVariant;
oEnum: IEnumvariant;
iValue: LongWord;

begin
Try
objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
colItems := objWMIService.ExecQuery('SELECT Caption, CSDVersion, Version FROM Win32_OperatingSystem', 'WQL', 0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
if oEnum.Next(1, Item, iValue)=0 then begin
Result := FullVersionString(Item);
exit;
end;
Except
// yes, I know this is nasty, but come what may I want to use the fallback code below should the WMI code fail
End;

(* Fallback, relies on the deprecated function GetVersionEx, reports erroneous values
when manifest does not contain supportedOS matching the executing system *)
Result := TOSVersion.ToString;
end;

关于delphi - 检查 W10 上的 Windows 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32378851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com