Delphi 正在检查W10上的Windows版本
有人知道TOSVersion.Name是否仍能在Windows 10上运行吗 我有一个vcl应用程序,它有一个表单显示事件,该事件获取操作系统详细信息,并使用SysUtils中的TOSVersion记录将其显示在TMemo框中Delphi 正在检查W10上的Windows版本,delphi,operating-system,windows-10,delphi-xe8,Delphi,Operating System,Windows 10,Delphi Xe8,有人知道TOSVersion.Name是否仍能在Windows 10上运行吗 我有一个vcl应用程序,它有一个表单显示事件,该事件获取操作系统详细信息,并使用SysUtils中的TOSVersion记录将其显示在TMemo框中 with mmoOSInfo.Lines do begin Clear; Add(TOSVersion.ToString); Add(''); Add('Architecture: ' + OSArchitectureToStr(TOS
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、台式PC、笔记本电脑和Surface Pro上执行时没有任何问题,但在Windows 10上安装时则没有
当我使用PASServer进行调试时,TOSVersion.Name返回为:='Windows8'。
我是否做错了什么,或者我对TOSVersion检测Windows 10的期望过高?未触发任何异常。在我可以访问的2台Windows 10计算机中,一条迁移路径来自Windows 8.1,另一条则来自Windows 7
非常感谢有两件事阻止您的代码返回正确版本:
TOSVersion
所依赖的版本将与该版本有关NetWkstaGetInfo
,这不受此版本的限制。尽管对NetWkstaGetInfo
的调用确实会泄漏内存,但这可能并不重要,因为它只被调用一次
与此主题相关的一些链接:
- 还有更多
- 将
选项添加到清单中,并包括Windows 10的GUID。这可以阻止supportedOS
撒谎。然后使用修改后的GetVersionEx
,或其他方法获取版本版本
- 使用WMI查询
- 调用
NetServerGetInfo
- 调用
NetWkstaGetInfo
- 调用
RtlGetVersion
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;
函数操作系统显示名称:字符串;
函数GetWMIObject(const objectName:string):IDispatch;
变量
chEaten:整数;
BindCtx:IBindCtx;
名字:伊莫尼克尔;
开始
olcheck(CreateBindCtx(0,bindCtx));
olcheck(MkParseDisplayName(BindCtx、PChar(objectName)、chEaten、名字对象));
OleCheck(名字对象BindToObject(BindCtx,nil,IDispatch,Result));
结束;
函数VarToString(const值:OleVariant):字符串;
开始
如果变量STR(值),则开始
结果:=微调(值);
结束,否则开始
结果:='';
结束;
结束;
函数FullVersionString(const项:OleVariant):字符串;
变量
标题、ServicePack、版本、体系结构:字符串;
开始
标题:=VarToString(Item.Caption);
ServicePack:=VarToString(Item.csd版本);
版本:=VarToString(Item.Version);
架构:=架构显示名称(SystemArchitecture);
结果:=标题;
如果是ServicePack“”,则开始
结果:=结果+“”+ServicePack;
结束;
结果:=结果+',版本'+版本+','+架构;
结束;
变量
objWMIService:油变异体;
大肠菌群:油变异体;
项目:油变异体;
oEnum:IEnumvariant;
伊瓦鲁:长词;
开始
尝试
objWMIService:=GetWMIObject('winmgmts:\\localhost\root\cimv2');
colItems:=objWMIService.ExecQuery('SELECT Caption,CSDVersion,Version FROM Win32_OperatingSystem','WQL',0);
oEnum:=IUnknown(colItems.\u NewEnum)作为IEnumVariant;
如果oEnum.Next(1,项,值)=0,则开始
结果:=完整版本字符串(项目);
出口
结束;
除了
//是的,我知道这很糟糕,但是如果WMI代码失败,我可能想使用下面的回退代码
结束;
(*回退,依赖于不推荐使用的函数GetVersionEx,报告错误的值
清单不包含与执行系统*匹配的支持对象时*)
结果:=TOSVersion.ToString;
结束;
您是否尝试过使用自定义清单
我使用XE8,并且在使用针对Windows 8.1和Windows 10的清单文件时,识别Windows 10的版本没有问题
我的自定义清单是为了让我的应用程序“Windows 10”知晓
具体如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="MrTheV Dev"
version="11.0.2804.9245"
processorArchitecture="*"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="False"/>
</requestedPrivileges>
</security>
</trustInfo>
<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>
</assembly>
@杰瑞道奇,别再这样了。毫无疑问,根据营销类型,新版本正是您所需要的。您必须热爱营销:)-除此之外。如果我看一下这个链接(),将supportedOS条目添加到清单中还有其他含义。在答案中加入这一点也许是个好主意。非常感谢海夫曼先生。我非常感谢您对Delphi编程知识的深刻理解。另一个选择是从
kernel32.dll
中阅读版本,请参阅我尝试了您的代码,它除了编译体系结构DisplayName(SystemArchitecture)
之外都可以编译。两个函数/变量/常量似乎都未知。我必须在uses
子句中包含哪个文件来修复此问题?我已经包括了ActiveX
。抱歉,上面的链接-我刚刚在Win 10上测试了该库,但它不起作用!
Windows (Version 10.0, Build 14393, 64-bit Edition)