有人知道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迁移的。
非常感谢
最佳答案
有两件事阻止您的代码返回正确的版本:
GetVersionEx
所依赖的 TOSVersion
将取决于版本。 我相信XE8更新1确实将版本检测更改为使用不受此版本谎言约束的
NetWkstaGetInfo
。尽管对NetWkstaGetInfo
的调用确实会泄漏内存,但这并不重要,因为它仅被调用了一次。一些与此主题有关的链接:
GetVersionEx
如果您绝对必须将版本报告给用户,那么您可以有多种选择:
supportedOS
选项添加到 list 中,并包括Windows 10的GUID。这可以阻止GetVersionEx
说谎。然后,使用TOSVersion
的修改版本或其他某种方式来获取该版本。 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/