【问题标题】:Windows Version With Edition [closed]Windows 版本与版本 [关闭]
【发布时间】:2013-03-28 08:07:32
【问题描述】:

我有一个项目使用 Delphi XE2 显示版本类型从“Windows 95”到“Windows 8”的 Windows 版本。首先,我尝试了“TOSVersion”功能。但问题是:

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
  VersionNameOfOperatingSystem : String;
begin
  VersionNameOfOperatingSystem := TOSVersion.Name;
  Edit01.Text := VersionNameOfOperatingSystem;
end

在 Windows 8 环境中仅显示“Windows”,另一个问题是 Ii 无法检测到“Windows 版”。然后我尝试了“GetProductInfo”功能。但这里还有一个问题:

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 0, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 1, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 2, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 2, 2, 2, @rpt) then Edit02.Text :=IntToStr(rpt);
end

如果我在 Windows Vista Enterprise SP2 中运行已编译的 exe 文件,则产生相同的结果,并且不能使用早期版本的 Windows。如果我按如下方式调用“TOSVersion”

begin
  TOSVersion.Platform of
    pfWindows : 
      begin
      .
      .
      .
      .
      end
    else
      beging
      .
      .
      .
      end
end;

然后调用“GetProductInfo”然后我得到“错误”,告诉两者不能同时调用。 最后我尝试了“OSVERSIONINFO 结构”来识别它是否是“服务器”和“Windows XP 版本类型”的“GetVersionEx 函数”。我完全困惑如何开始我的编程。这个论坛有很多经验丰富的程序员。任何人都可以写下完整的程序。我用谷歌搜索了它,但所有可用的程序都没有更新到“Windows 7”。此论坛中的一个可用版本也是“Windows 7”且未更新。请不要告诉“我们不能坐在您的键盘前为您输入代码”。请帮帮我。

【问题讨论】:

  • 您要求我们编写一个完整的程序来解决您的确切问题。这就是一个过于本地化的问题的定义。所有信息都在您最近的其他问题中。
  • 我再次尝试了 Ken 的代码,我收到错误,因为“[DCC 警告] Unit1.pas(148): W1036 变量 'dwOSMajorVersion' 可能尚未初始化”“[DCC 警告] Unit1. pas(148): W1036 变量 'dwOSMinorVersion' 可能尚未初始化" "[DCC 警告] Unit1.pas(148): W1036 变量 'dwSpMajorVersion' 可能尚未初始化" "[DCC 警告] Unit1.pas(148) :W1036 变量“dwSpMinorVersion”可能尚未初始化”。但我也无法显示“Result”和“tmpStr”的字符串。如果我定义 "Edit1.Text :=Result; 和 Edit2.Text:=tmpStr; 给出错误。
  • 好的,我尝试编译 Ken 的代码。它不编译。它很穷。这是一个可以编译的版本。我没有全面测试过:pastebin.com/RZd1Ag4u
  • 我的旧帖子中的代码已修复(自我注意:永远不要在此处发布您找到但从未编译过的代码)。现在可以编译,并且对 Windows 8 的支持最少。由于某种原因,它在我尚未追踪的 Win7 Pro (OEM) 上返回 Windows 7 Unknown Product
  • 请告诉我 Ken 的代码中的“NTBres”和“BRes”到底在做什么。

标签: delphi delphi-xe2


【解决方案1】:

在我看来,您最近的所有问题都与以下问题有关:

  1. 您想要获取操作系统的完整产品名称。您尝试过的各种示例代码都有缺陷。例如,您尝试过的许多示例都无法识别 Windows 8。
  2. 您想知道产品类型。您希望检测 Ultimate 版本。

我建议您使用 WMI 来执行此操作。这将在未来证明您的代码可以在尚未发布的 Windows 版本上运行。

对于我的 WMI 代码,我无耻地重复使用了这个答案中的 WMI 专家 RRUZ 的代码:How do I use WMI with Delphi without drastically increasing the application's file size?

unit SimpleWMI;

interface

uses
  SysUtils, ActiveX, ComObj, Variants;

function GetWMIprops(const wmiHost, root, wmiClass: string; const wmiProps: array of string): TArray<string>;

implementation

function GetWMIprops(const wmiHost, root, wmiClass: string; const wmiProps: array of string): TArray<string>;
var
  objWMIService: OLEVariant;
  colItems: OLEVariant;
  colItem: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;

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

var
  i: Integer;

begin
  objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s', [wmiHost, root]));
  colItems := objWMIService.ExecQuery(Format('SELECT * FROM %s', [wmiClass]), 'WQL', 0);
  oEnum := IUnknown(colItems._NewEnum) as IEnumvariant;
  SetLength(Result, Length(wmiProps));
  while oEnum.Next(1, colItem, iValue) = 0 do
    for i := 0 to high(wmiProps) do
      Result[i] := colItem.Properties_.Item(wmiProps[i], 0);
end;

end.

所以现在你可以用这个简单的程序解决你的问题了:

program OSVersionDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows,
  ActiveX,
  SimpleWMI in 'SimpleWMI.pas';

function IsUltimateEdition(ProductType: DWORD): Boolean;
begin
  Result := ProductType in [PRODUCT_ULTIMATE,PRODUCT_ULTIMATE_N,PRODUCT_ULTIMATE_E];
end;

var
  PropValues: TArray<string>;
  ProductType: DWORD;

begin
  CoInitialize(nil);
  try
    PropValues := GetWMIprops('.', 'root\CIMV2', 'Win32_OperatingSystem', ['Caption', 'Version', 'OperatingSystemSKU']);
    Writeln('OS Name: ' + PropValues[0]);
    Writeln('Version: ' + PropValues[1]);
    ProductType := StrToInt(PropValues[2]);
    Writeln('Ultimate edition: ' + BoolToStr(IsUltimateEdition(ProductType), True));

    Readln;
  finally
    CoUninitialize;
  end;
end.

在我的机器上输出是:

操作系统名称:Microsoft Windows 7 Professional 版本:6.1.7601 终极版:假

Win32_OperatingSystem 类加载了更多信息。因此,如果您想获取服务包信息,请询问CSDVersion 属性。像这样:

PropValues := GetWMIprops('.', 'root\CIMV2', 'Win32_OperatingSystem', ['Caption', 'Version', 'OperatingSystemSKU', 'CSDVersion']);
Writeln('OS Name: ' + Trim(PropValues[0]) + ' ' + Trim(PropValues[3]));
Writeln('Version: ' + PropValues[1]);
ProductType := StrToInt(PropValues[2]);
Writeln('Ultimate edition: ' + BoolToStr(IsUltimateEdition(ProductType), True));

我希望这可以为您提供足够的信息来填写您实际需要的问题。

虽然您说要支持 Windows 95、98 和 ME,但请注意,使用 Unicode 版本的 Delphi(例如 XE2)生成的程序无法在这些古老的系统上运行。

【讨论】:

    猜你喜欢
    • 2013-08-02
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2016-02-01
    • 2019-03-24
    • 2011-07-29
    • 2015-08-27
    相关资源
    最近更新 更多