-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」しか表示されず、「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

コンパイルされた exe ファイルを Windows Vista Enterprise SP2 で実行すると、同じ結果が生成され、以前のバージョンの Windows では同じ結果が得られません。次のように「TOSVersion」を呼び出すと

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

「GetProductInfo」を呼び出すと、両方を同時に呼び出すことができないことを示す「エラー」が表示されます。最後に、「OSVERSIONINFO 構造体」で「サーバー」かどうかを識別し、「Windows XP Edition タイプ」の「GetVersionEx 関数」を試してみました。プログラミングを開始する方法が完全に混乱しています。このフォーラムには経験豊富なコーダーがたくさんいます。誰でも完全なプログラムを書き留めることができます。私はそれをグーグルで検索しましたが、利用可能なすべてのプログラムは「Windows 7」まで更新されていません。また、このフォーラムで利用できるのは、「Windows 7」までであり、更新されていません。「キーボードの前に座ってコードを入力することはできません」と言わないでください。私を助けてください。

4

1 に答える 1

2

あなたの最近の質問はすべて次の問題に関連しているように私には思えます:

  1. オペレーティング システムの完全な製品名を取得します。あなたが試したさまざまなサンプル コードには欠陥があります。たとえば、試したサンプルの多くは Windows 8 を認識しません。
  2. 商品の種類を知りたい。Ultimate エディションを検出したいと考えています。

これには WMI を使用することをお勧めします。これにより、コードが将来的に証明され、まだリリースされていないバージョンの Windows で動作するようになります。

私の WMI コードについては、WMI の専門家である RRUZ のコードを次の回答から恥知らずに再利用しました:アプリケーションのファイル サイズを大幅に増やすことなく Delphi で WMI を使用するには

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名:Microsoft Windows 7 Professional
バージョン: 6.1.7601
アルティメット エディション: False

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 をサポートしたいとおっしゃっていますが、Delphi の Unicode バージョン (XE2 など) で作成されたプログラムは、これらの古いシステムでは動作しないことに注意してください。

于 2013-03-28T10:29:14.327 に答える