-4

我有一个项目使用 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”且未更新。请不要告诉“我们不能坐在您的键盘前为您输入代码”。请帮我。

4

1 回答 1

2

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

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

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

对于我的 WMI 代码,我从这个答案中无耻地重新使用了 WMI 专家 RRUZ 的代码:如何在不显着增加应用程序文件大小的情况下将 WMI 与 Delphi 一起使用?

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-03-28T10:29:14.327 回答