Windows版本与版本

时间:2013-03-28 08:07:32

标签: delphi delphi-xe2

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

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

在Windows 8环境中仅显示“Windows”,另一个问题是Ii无法检测到“Windows Edition”。然后我尝试了“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”并且未更新。请不要告诉“我们不能坐在您的键盘上并为您键入代码”。请帮帮我。

1 个答案:

答案 0 :(得分:2)

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

  1. 您想获得操作系统的完整产品名称。您尝试过的各种示例代码都存在缺陷。例如,您尝试过的许多示例都无法识别Windows 8。
  2. 您想知道产品类型。您希望检测终极版本。
  3. 我建议您使用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.
    

    在我的机器上输出为:

    OS Name: Microsoft Windows 7 Professional
    Version: 6.1.7601
    Ultimate edition: False
    

    Win32_OperatingSystem类加载了更多信息。因此,如果您想获取Service Pack信息,请询问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)生成的程序不能在这些古老的系统上运行。