Delphi Programming / Object Pascal
[掲載 2014年04月29日] [更新 2015年11月13日] Delphi 一般・その他
Windows のバージョンの取得
動作確認等
Windows 7 U64(SP1) + Delphi XE(UP1) Pro, 一部 Delphi XE5(UP2) Pro
2015年11月09日
互換モード関係の記事を追加
2015年11月10日
Windows のバージョン取得の具体的なコードと実行結果を掲載
Windows のパーション取得関係のリンクも本ページを主体とした
2015年11月12日
RtlGetVersion 関数の記事を DLL 内の関数の使用例の説明に利用できるように追加編集
その他,実行結果の画像追加等
2015年11月13日
WMI による Windows のバージョン取得だけのコードと実行結果の図を掲載
Windows のバージョンの取得と Windows 8.1 以降における注意
Windows のバージョンを自アプリで取得するため参考コードです.
WMI を使用した方法以外では,アプリケーションマニフェストを使用して,そのマニフェストファイルの compatibility に該当バージョンの ID の記述がないと,正しいバージョンの値が取得できない場合があります.
何故そのような「偽造工作」がされるのかは謎です.
本ページのテストで使用している関数類が,実際にはどのように Windows のバージョンを取得しているかの内部処理については,筆者は知りません.
この他,レジストリから取得したり,システムの関係の DLL の製品バージョンから取得する方法も考えられます.必要があれば検討してみてください.
[ファイル名を指定して実行] 等で,以下のコマンドを実行するとシステム情報,あるいはバージョン情報ダイアログが表示されます.Windows のバージョンは,そのダイアログで確認できます.
control.exe /name Microsoft.System
msinfo32.exe
winver.exe
//コマンドプロンプト専用
ver
systeminfo
[備考]
Windows 10 TP(Technical Preview)のバージョンは 6.4 です.
Windows 10 では,バージョンの表記方式が変更されているようです.
2015年12月17日日現在では,Windows 10 バージョン 1511 ビルド 10586.36 ということになるようですが,筆者は,正確な表記方法を知りません.
01_ Windows のバージョン取得 - CheckWin32Version 関数
CheckWin32Version 関数は,正確には,現在の Windows が,指定したバージョンより上位または下位のバージョンかをチェックする関数です.
同じような機能を持つ VerifyVersionInfo という関数があります.VerifyVersionInfo は Windows 2000 以降で使用可能です.後述の TOSVersion にも同様のメソッドが実装されています.
下図は,compatibility に Windows のバージョンの
ID を記述したアプリケーションマニフェストを使用してテストした結果です.このアプリケーションマニフェストを使用しないと,Windows 8.1 以上では正しい結果が取得できません.
CheckWin32Version 関数は Delphi 6(UP2) 以降で使用可能で,Windows 95 以降の Windows のバージョンの判定に使用できます.
互換モードで実行している場合は,互換モードの Windows のバージョンで判定されます.
[備考]
Delphi 6 では,CheckWin32Version 関数の戻り値の論理値が逆になっています.以下からダウンロードしたプロジェクトを Delphi 6 の IDE でコンパイルして実行すると修正されます.
図1
Windows 7 での実行結果
図2
Windows 8.1 での実行結果
図3
Windows 10 での実行結果
copy code
// =============================================================================
// CheckWin32Versionを使用したWindowsのバージョンによる条件分岐
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LVersion : String ;
begin
if CheckWin32Version(10 , 0 ) then begin
LVersion := 'Windows 10' ;
end else
if CheckWin32Version(6 , 3 ) then begin
LVersion := 'Windows 8.1' ;
end else
if CheckWin32Version(6 , 2 ) then begin
LVersion := 'Widows 8' ;
end else
if CheckWin32Version(6 , 1 ) then begin
LVersion := 'Widows 7' ;
end else
if CheckWin32Version(6 , 0 ) then begin
LVersion := 'Widows Vista' ;
end else
if CheckWin32Version(5 , 1 ) then begin
LVersion := 'Widows XP' ;
end else
if CheckWin32Version(5 , 0 ) then begin
LVersion := 'Widows 2000' ;
end else
if CheckWin32Version(4 , 90 ) then begin
LVersion := 'Widows ME' ;
end else
if CheckWin32Version(4 , 10 ) then begin
LVersion := 'Widows 98, 98SE' ;
end else
if CheckWin32Version(4 , 0 ) then begin
LVersion := 'Widows 95' ;
end else begin
LVersion := 'Unknown Version' ;
end ;
MessageBox(Handle, PChar(LVersion), 'Windows Version' , MB_ICONINFORMATION);
end ;
02_ Windows のバージョン取得 - GetVersionEx 関数
GetVersionEx 関数を使用したテストコードです.
下図は,compatibility に Windows のバージョンの ID を記述したアプリケーションマニフェストを使用してテストした結果です.このアプリケーションマニフェストを使用しないと,Windows 8.1 以上では正しい結果が取得できません.
GetVersionEx 関数は,Windows 95 以降のバージョンを検出できます.
互換モードで実行している場合は,互換モードの Windows のバージョンの値となります.
図4
Windows 7 での実行結果
図5
Windows 8.1 での実行結果
図6
Windows 10 での実行結果
[備考]
Widows 10 は正式リリース後,ビルド番号がかなり変化しています.2015年11月05日現在のビルド番号は 10586 となっています.
copy code
implementation
{$R *.dfm}
type
TOSVERSIONINFOEX = packed record
dwOSVersionInfoSize : Cardinal;
dwMajorVersion : Cardinal;
dwMinorVersion : Cardinal;
dwBuildNumber : Cardinal;
dwPlatformId : Cardinal;
szCSDVersion : array [0 ..127 ] of Char;
wServicePackMajor : WORD;
wServicePackMinor : WORD;
wSuiteMask : WORD;
wProductType : Byte;
wReserved : Byte;
end ;
// =============================================================================
// GetVersionEx関数を使用したWindowsのバージョンの取得
// TOSVERSIONINFOEX構造体のメンバから取得する
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LGetVersionEx : function (var LPOSVERSIONINFO: TOSVERSIONINFOEX): Boolean; stdcall ;
LDLLHandle : THandle;
LVersion : TOSVersionInfoEx;
LMajor : Cardinal;
LMinor : Cardinal;
LBuild : Cardinal;
LCSDVersion : String ;
LText : String ;
LRetFlag : Boolean;
begin
LRetFlag := False;
LDLLHandle := LoadLibrary('kernel32.dll' );
if LDLLHandle <> 0 then begin
try
{$IFDEF UNICODE}
@LGetVersionEx := GetProcAddress(LDLLHandle, 'GetVersionExW' );
{$ELSE}
@LGetVersionEx := GetProcAddress(LDLLHandle, 'GetVersionExA' );
{$ENDIF}
if @LGetVersionEx <> nil then begin
LVersion.dwOSVersionInfoSize := SizeOf(LVersion);
FillChar(LVersion.szCSDVersion, SizeOf(LVersion.szCSDVersion), #0 );
if LGetVersionEx(LVersion) then begin
LRetFlag := True;
LMajor := LVersion.dwMajorVersion;
LMinor := LVersion.dwMinorVersion;
LBuild := LVersion.dwBuildNumber;
LCSDVersion := LVersion.szCSDVersion;
LText := IntToStr(LMajor) + '.' + IntToStr(LMinor) + '.' + IntToStr(LBuild)
+ sLineBreak + LCSDVersion;
end ;
end ;
finally
FreeLibrary(LDLLHandle);
end ;
end ;
if not LRetFlag then begin
MessageBox(Handle, 'Unknown Version' , 'Windows Version' , MB_ICONINFORMATION);
end else begin
MessageBox(Handle, PChar(LText), 'Windows Version' , MB_ICONINFORMATION);
end ;
end ;
03_ RtlGetVersion 関数でバージョン取得 - DLL の静的リンク
RtlGetVersion 関数を使用するテストコードです.
この関数の機能は GetVersionEx 関数とほとんど同じですが,アプリケーションマニフェストを使用しなくても,Windows 8.1 以上で正しい Windows のバージョンの値を取得することができます.
RtlGetVersion 関数は,Windows 2000 以上で使用可能です.
実行結果は,前項の GetVersionEx 関数の場合と全く同じとなります.
互換モードで実行している場合は,互換モードの Windows のバージョンの値となります.
[備考]
RTL_OSVERSIONINFOEXW と OSVERSIONINFOEXW は同じ中身の構造体です.
copy code
implementation
{$R *.dfm}
function RtlGetVersion(var AVersion: TOSVersionInfoExW): Integer;
stdcall ; external 'ntdll.dll' ;
// =============================================================================
// RtlGetVersion関数を使用したWindowsのバージョンの取得
// TOSVersionInfoExW構造体のメンバから取得する
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LVersion : TOSVersionInfoExW;
LMajor : Cardinal;
LMinor : Cardinal;
LBuild : Cardinal;
LCSDVersion : String ;
LText : String ;
begin
LVersion.dwOSVersionInfoSize := SizeOf(LVersion);
FillChar(LVersion.szCSDVersion, SizeOf(LVersion.szCSDVersion), #0 );
if RtlGetVersion(LVersion) = 0 then begin
LMajor := LVersion.dwMajorVersion;
LMinor := LVersion.dwMinorVersion;
LBuild := LVersion.dwBuildNumber;
LCSDVersion := LVersion.szCSDVersion;
LText := IntToStr(LMajor) + '.' + IntToStr(LMinor) + '.' + IntToStr(LBuild)
+ sLineBreak + LCSDVersion;
MessageBox(Handle, PChar(LText), 'Windows Version' , MB_ICONINFORMATION);
end ;
end ;
04_ RtlGetVersion 関数でバージョン取得 - DLL の動的リンク ( 1 )
RtlGetVersion 関数は,Windows 9X では使用できません.アプリケーションを Windows 9X で使用されてしまう可能性がある場合は,下のように DLL を実行時にロードして,その DLL がシステムに存在するのか,その DLL 内に,該当する関数が実装されているかを確認するようにします.
このような方法を「 DLL の動的リンク」言うことがあります.一方,上のコードのような方法を「DLL の静的リンク」と言っています.
アプリケーションを Windows 2000 以前で動作させるためには,Ansi 版である Delphi 2007 以前でコンパイルして EXE を作成します.
下図は,Windows 7 U64(SP1) + Delphi 2007-R2 で作成した EXE を実行した結果です.Delphi 2007 には TOSVersionInfoExW 構造体が実装されていないので,コード内で定義しています.
このコードは,Delphi 6, 7, 2007-R2 で動作確認しています.Delphi 2007 以降でも使用可能です.
図7
Windows 98 での実行結果
図8
Windows 2000(SP4) での実行結果
Service Pack 4 がインストールされているが表示されていない
図9
Windows XP(SP3) での実行結果
copy code
implementation
{$R *.dfm}
type
TOSVERSIONINFOEXW = packed record
dwOSVersionInfoSize : Cardinal;
dwMajorVersion : Cardinal;
dwMinorVersion : Cardinal;
dwBuildNumber : Cardinal;
dwPlatformId : Cardinal;
szCSDVersion : array [0 ..127 ] of WideChar;
wServicePackMajor : WORD;
wServicePackMinor : WORD;
wSuiteMask : WORD;
wProductType : Byte;
wReserved : Byte;
end ;
// =============================================================================
// RtlGetVersion関数を使用したWindowsのバージョンの取得
// TOSVersionInfoExW構造体のメンバから取得する
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LRtlGetVersion : function (var AVersion: TOSVersionInfoExW): Integer; stdcall ;
LDLLHandle : THandle;
LVersion : TOSVersionInfoExW;
LMajor : Cardinal;
LMinor : Cardinal;
LBuild : Cardinal;
LCSDVersion : String ;
LText : String ;
LRetFlag : Boolean;
begin
LRetFlag := False;
LDLLHandle := LoadLibrary('ntdll.dll' );
if LDLLHandle <> 0 then begin
try
@LRtlGetVersion := GetProcAddress(LDLLHandle, 'RtlGetVersion' );
if @LRtlGetVersion <> nil then begin
LRetFlag := True;
LVersion.dwOSVersionInfoSize := SizeOf(LVersion);
FillChar(LVersion.szCSDVersion, SizeOf(LVersion.szCSDVersion), #0 );
if LRtlGetVersion(LVersion) = 0 then begin
LMajor := LVersion.dwMajorVersion;
LMinor := LVersion.dwMinorVersion;
LBuild := LVersion.dwBuildNumber;
LCSDVersion := LVersion.szCSDVersion;
LText := IntToStr(LMajor) + '.' + IntToStr(LMinor) + '.' + IntToStr(LBuild)
+ sLineBreak + LCSDVersion;
ShowMessage(LText);
end ;
end ;
finally
FreeLibrary(LDLLHandle);
end ;
end ;
if not LRetFlag then begin
ShowMessage('このパソコンでは使用できません.' );
Close;
end ;
end ;
end .
05_ RtlGetVersion 関数でバージョン取得 - DLL の動的リンク ( 2 )
上のコードは,DLL 内の関数 RtlGetVersion をイベント内だけで使用する場合です.
ユニット内の別の場所でもこの関数を使用する場合は,以下のように,関数をグローバルに type 宣言して使用します.実際には,DLL のロードや関数のアドレスの取得も,OnCreate イベント内等で処理することになるでしょう.他のユニットからも利用できるようにするには,implementation 部ではなく,interface 部で宣言します.
下のコードでは,TRtlGetVersion という,関数名と同じ名前の型にしていますが,これは任意の名前にできます.
このコードも,もちろん,Delphi 2007 以降でも使用可能です.
copy code
implementation
{$R *.dfm}
type
TOSVERSIONINFOEXW = packed record
dwOSVersionInfoSize : Cardinal;
dwMajorVersion : Cardinal;
dwMinorVersion : Cardinal;
dwBuildNumber : Cardinal;
dwPlatformId : Cardinal;
szCSDVersion : array [0 ..127 ] of WideChar;
wServicePackMajor : WORD;
wServicePackMinor : WORD;
wSuiteMask : WORD;
wProductType : Byte;
wReserved : Byte;
end ;
TRtlGetVersion = function (var AVersion: TOSVersionInfoExW): Integer; stdcall ;
var
LRtlGetVersion : TRtlGetVersion;
// =============================================================================
// RtlGetVersion関数を使用したWindowsのバージョンの取得
// TOSVersionInfoExW構造体のメンバから取得する
//
// グローバルでType宣言で定義した関数を使用する例
// TRtlGetVersionとしているが,この名前は任意
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LDLLHandle : THandle;
LVersion : TOSVersionInfoExW;
LMajor : Cardinal;
LMinor : Cardinal;
LBuild : Cardinal;
LCSDVersion : String ;
LText : String ;
LRetFlag : Boolean;
begin
LRetFlag := False;
LDLLHandle := LoadLibrary('ntdll.dll' );
// 以下省略(上のコードと同じ)
06_ TOSVersion による Windows のバージョン取得
Delphi XE2 以降であれば,SysUtils.TOSVersion のメソッドやプロパティが利用できます.
TOSVersion.Check メソッドではサービスパックも含めたチェックができます.レコード型のクラスメソッドですから TOSVersion を Create する必要はありません.
下図は,compatibility に Windows のバージョンの ID を記述したアプリケーションマニフェストを使用してテストした結果です.このアプリケーションマニフェストを使用しないと,Windows 8.1 以上では正しい結果が取得できません.
TOSVersion を使用したプログラムは,Windows XP 以降で実行可能です.
互換モードで実行している場合は,互換モードの Windows のバージョンの値となります.
図10
Windows 7 での実行結果
図11
Windows 8.1 での実行結果
図12
Windows 10 での実行結果
copy code
// =============================================================================
// TOSVersionによるWindowsのバージョンの取得
// メジャー,マイナーバージョン番号等も独立して取得可能
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LVersion : String ;
LText : String ;
begin
LText := TOSVersion.Name + sLineBreak + TOSVersion.ToString;
MessageBox(Handle, PChar(LText), '情報' , MB_ICONINFORMATION);
end ;
07_ WMI を使用した Windows のバージョン取得
Windows のバージョン情報等は,WMI の Win32_OperatingSystem でも取得できます.
下図は,[900] [01_コンピュータシステムの情報を取得] のサンプルの Edit1 にクラス名を入力してクエリを実行した結果です.
WMI を使用したこの方法は,このアプリケーションマニフェストを使用しなくても正しい Windows のバージョンの値を取得することができます.また,Windows のビットバージョン,サービスパックのバージョンやエディションの種類も取得できます.
互換モードで実行している場合も,取得情報はシステムの Windows のバージョンの値です.
Windows のバージョン情報の取得としては,WMI を使用した方法が最も確実と思われますが,Windows 2000 以降に限られます.
図13
Windows 7 での実行結果
図14
Windows 8.1 での実行結果
図15
Windows 10 での実行結果
WMI は Windows 2000 以上で使用可能です.Windows 95, Windows 98, Windows NT4.0 で WMI を使用するには別途インストールが必要ですが,既にサポートが終了しているバージョンです.ダウンロードが可能であるかは確認していません.
図16
Windows 2000(SP4) での実行結果
EXE は Windows 7 U64(SP1) + Delphi XE(UP1) Pro で作成
図17
Windows XP(SP3) での実行結果
EXE は Windows 7 U64(SP1) + Delphi XE(UP1) Pro で作成
08_ WMI を使用して Windows のバージョンだけを取得
以下のコードは,WMI を使用して Windows のバージョンの値だけを文字列として取得するコードと,その実行結果です.
uses に WbemScripting_TLB, ActiveX が必要です.
図18
Windows 7 での実行結果
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, WbemScripting_TLB, ActiveX;
type
TForm1 = class (TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
function GetWMIPropSetEnum(ASQLText: WideString): IEnumVariant;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.dfm}
// =============================================================================
// Win32_OperatingSystemクラスからVersionプロパティの値を取得
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LIEmunVariant : IEnumVariant;
LobjTemp : OleVariant;
LValue : LongWord;
LwmiPropSet : ISWbemPropertySet;
LwmiProperty : ISWbemProperty;
LText : String ;
begin
// プロパティのセットのコレクションを取得
LIEmunVariant := GetWMIPropSetEnum('Win32_OperatingSystem' );
// OSの情報はおそらく1つだけなので実際には1回しかループしない
while LIEmunVariant.Next(1 , LobjTemp, LValue) = 0 do begin
// プロパティのセットを取得
LwmiPropSet := (IUnknown(LobjTemp) as ISWBemObject).Properties_;
// Versionプロパティを取得
LwmiProperty := LwmiPropSet.Item('Version' , 0 );
LText := LwmiProperty.Name + sLineBreak + LwmiProperty.Get_Value;
MessageBox(Handle, PChar(LText), '情報' , MB_ICONINFORMATION);
end ;
end ;
// -----------------------------------------------------------------------------
// WMIのクエリを実行してプロパティのセットのコレクションを取得するルーチン
// -----------------------------------------------------------------------------
function TForm1.GetWMIPropSetEnum(ASQLText: WideString): IEnumVariant;
var
LISWbemLocator : ISWbemLocator;
LISWbemService : ISWbemServices;
LSWbemObjectSet : ISWbemObjectSet;
begin
// WMIのオブジェクトを生成
LISWbemLocator := CoSWbemLocator.Create;
// WMIサービスに接続
LISWbemService := LISWbemLocator.ConnectServer(
'' ,
'root\cimv2' ,
'' ,
'' ,
'' ,
'' ,
0 ,
nil );
// クエリーを実行して,プロパティのセットのオブジェクトを取得
LSWbemObjectSet := LISWbemService.ExecQuery(
'Select * From ' + ASQLText,
'WQL' ,
wbemFlagReturnImmediately,
nil );
// プロパティのセットのコレクションを取得
Result := LSWbemObjectSet._NewEnum as IEnumVariant;
end ;
end .
プロパティの値は,次のように,直接 OleVariant 型の値として取得することもできます.
copy code
// =============================================================================
// Win32_OperatingSystemクラスからVersionプロパティの値を取得
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LIEmunVariant : IEnumVariant;
LobjTemp : OleVariant;
LValue : LongWord;
LText : String ;
begin
// プロパティのセットのコレクションを取得
LIEmunVariant := GetWMIPropSetEnum('Win32_OperatingSystem' );
// OSの情報はおそらく1つだけなので実際には1回しかループしない
while LIEmunVariant.Next(1 , LobjTemp, LValue) = 0 do begin
// Versionプロパティを取得
LText := LobjTemp.Version;
LText := 'Verstion' + sLineBreak + LText;
MessageBox(Handle, PChar(LText), '情報' , MB_ICONINFORMATION);
end ;
end ;
タイプライブラリの取り込みで WbemScripting_TLB を作成するのは面倒だし,WbemScripting_TLB は使いたくないという場合は,以下のように,全て OleVariant 型で処理することになります.
copy code
implementation
uses
ActiveX,
ComObj;
{$R *.dfm}
// =============================================================================
// Win32_OperatingSystemクラスからVersionプロパティの値を取得
//
// IEnumVariantの使用にはusesにActiveXが必要
// CreateOleObjectの使用にはusesにComObjが必要
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LSQLText : WideString;
LISWbemLocator : OleVariant;
LISWbemService : OleVariant;
LSWbemObjectSet : OleVariant;
LIEmunVariant : IEnumVariant;
LobjTemp : OleVariant;
LValue : LongWord;
LText : String ;
begin
LSQLText := 'Win32_OperatingSystem' ;
// WMIのオブジェクトを生成
LISWbemLocator := CreateOleObject('WbemScripting.SWbemLocator' );
// WMIサービスに接続
LISWbemService := LISWbemLocator.ConnectServer('' , 'root\cimv2' );
// クエリーを実行して,プロパティのセットのオブジェクトを取得
LSWbemObjectSet := LISWbemService.ExecQuery('SELECT * FROM ' + LSQLText);
// プロパティのセットのコレクションを取得
LIEmunVariant := IUnknown(LSWbemObjectSet._NewEnum) as IEnumVariant;
// 実際には1回しかループしない
while LIEmunVariant.Next(1 , LobjTemp, LValue) = 0 do begin
// Versionプロパティを取得
LText := LobjTemp.Version;
LText := 'Verstion' + sLineBreak + LText;
MessageBox(Handle, PChar(LText), '情報' , MB_ICONINFORMATION);
end ;
end ;
09_ ver コマンドで Windows のバージョンを確認
コマンドプロセッサの ver コマンドを使用すると,現在の Windows のバージョンを簡単に確認することができます.リファレンスとして利用できます.
図19
コマンドプロンプトで ver コマンドを実行
10_ 互換モードでの Windows のバージョンと互換モードの取得
互換モードで動作させているプログラムの場合,取得する Windows のバージョンの値は,バージョンの取得に使用する方法によって異なります.下記のリンクの記事も参考にしてください.
下のコードは,自分自身が互換モードで動作するように設定してある場合に,その互換モードの値を取得するサンプルです.互換モードの値は,アプリケーションのフルパスを使用して,レジストリから読み取ります.
図20
[プロパティ] のダイアログで [互換モード] 設定
図21
実行結果
Windows 2000 の場合は WIN2000 となる
互換モードの値は,レジストリの以下のキーにあります.このキー内の各項目が,互換モードを設定しているプログラムのフルバスです.この項目 (名前) のデータが互換モードの値です.
筆者の環境では,今回テスト用に設定したプログラムだけとなっています.
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
現在のコンピュータの全ユーザの互換モードの設定は,以下の場所に記録されます.
逆に,これらのレジストリを操作することにより,互換モードを設定することができます.
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
図22
copy code
// =============================================================================
// 自分自身が互換モードで動作しているかを調査
// 互換モードで動作している場合はその種類を取得して表示
//
// TRegistryの使用にはusesにRegistryが必要
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LAppFullPath : String ;
LRegistry : TRegistry;
LRegKeyName : String ;
LRegItemValue : String ;
begin
LAppFullPath := Application.ExeName;
LRegistry := TRegIniFile.Create;
try
LRegistry.Access := KEY_READ;
LRegistry.RootKey := HKEY_CURRENT_USER;
LRegKeyName := 'Software\Microsoft\Windows NT\CurrentVersion\'
+ 'AppCompatFlags\Layers' ;
LRegItemValue := '' ;
if LRegistry.OpenKey(LRegKeyName, False) then begin
LRegItemValue := LRegistry.ReadString(LAppFullPath);
end ;
if LRegItemValue = '' then begin
MessageBox(Handle, '互換モードは未設定です' , '互換モード' , MB_ICONINFORMATION);
end else begin
MessageBox(Handle, PChar(LRegItemValue), '互換モード' , MB_ICONINFORMATION);
end ;
finally
FreeAndNil(LRegistry);
end ;
end ;
11_ Windows 7 以降では EXE は Vista 互換モードで実行される
Windows 7 以降では,アプリケーションマニフェストを使用して,compatibility に該当バージョンの ID の記述をしないと,Windows Vista 互換モードで動作します.
この時,この互換モードは上のコードでは検出できませんが,リソースモニタ (resmon.exe) の [オペレーティングシステムのコンテキスト] で確認することができます.
[オペレーティングシステムのコンテキスト] の列がない場合は,リソースモニタのタイトル部でマウスの右ボタンクリックのメニューから [列の選択] を選択します.現れたダイアログで [オペレーティングシステムのコンテキスト] にチェックを入れると表示できます.
互換モードを設定したプログラムは,このリソースモニタでは Windows 7 となります.
図23