誰もが少なくとも一度は最新のOSでは古いプログラムを実行できなかった状況に直面したと思いますが、この場合はWindows互換モードが役に立ちました。

このメカニズムの操作は、さまざまな機能のインターセプトと、指定されたバージョンのWindowsに特有の動作のエミュレーションに基づいています。たとえば、レジストリキー、ドキュメントのあるディレクトリなどがエミュレートされます。 これらすべては、プログラムが選択された環境で実行されていると考えるために必要です。
アプリケーションが互換モードで実行されている場合、GetVersionExを呼び出すと、Windowsのダミーバージョンが返されますが、これはおそらくOS調整などのシステムプログラムには適していません。 この場合の対処方法
エクスポートされた関数の分析
ネットワークの広大さの中で、システムライブラリにエクスポートされた関数の有無を検出する方法に出会いました。 コード例:
TDSiWindowsVersion = (wvUnknown, wvWin31, wvWin95, wvWin95OSR2, wvWin98, wvWin98SE, wvWinME, wvWin9x, wvWinNT3, wvWinNT4, wvWin2000, wvWinXP, wvWinNT, wvWinServer2003, wvWinVista); function DSiGetTrueWindowsVersion: TDSiWindowsVersion; function ExportsAPI(module: HMODULE; const apiName: string): boolean; begin Result := GetProcAddress(module, PChar(apiName)) <> nil; end; var hKernel32: HMODULE; begin hKernel32 := GetModuleHandle('kernel32'); Win32Check(hKernel32 <> 0); if ExportsAPI(hKernel32, 'GetLocaleInfoEx') then Result := wvWinVista else if ExportsAPI(hKernel32, 'GetLargePageMinimum') then Result := wvWinServer2003 else if ExportsAPI(hKernel32, 'GetNativeSystemInfo') then Result := wvWinXP else if ExportsAPI(hKernel32, 'ReplaceFile') then Result := wvWin2000 else if ExportsAPI(hKernel32, 'OpenThread') then Result := wvWinME else if ExportsAPI(hKernel32, 'GetThreadPriorityBoost') then Result := wvWinNT4 else if ExportsAPI(hKernel32, 'IsDebuggerPresent') then
このソリューションは興味深いものですが、Windowsの各バージョンのリリースには重要なサポートが必要なので、受け入れられるとは思いません。
WMIを使用する
ウィキペディアから
リテラル変換のWindows Management Instrumentation(WMI)は、Windows管理ツールキットです。 さらに、WMIは、Windowsプラットフォームを実行しているコンピューターインフラストラクチャのさまざまな部分の動作を集中管理および監視するための基本的な技術の1つです。
WMIからWindowsのバージョンを取得することもできます。 ドキュメントから、これはそのようなリクエストで実行できることがわかります:
SELECT Version FROM Win32_OperatingSystem
Windows XPとの互換モードで
WMI Explorerを起動すると、この値がエミュレートされていないことがわかります。

さらに、このメソッドは機能しますが、完全に文書化されていますが、時間がかかり、WMIを使用してプロジェクトに作業するために大量のコードを取り込む必要があります。
私たちはレジストリを探しています
おそらく、ネットワークで見られる最もエレガントで正しい方法は、レジストリの値を覗くことです。
HLKM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion
さて、試してみましょう:
with TRegistry.Create do try RootKey := HKEY_LOCAL_MACHINE; if OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion') then Edit1.Text := ReadString('CurrentVersion'); finally Free; end;
残念ながら、Windows 7でテストした結果、このレジストリキーがエミュレートされていることがわかりました。 以前のバージョンのWindowsではこの方法は機能していたようですが、残念ながら
このトリックは機能しません 。
kernel32.dllバージョンの分析
私は自分で確認しませんでしたが、kernel32.dllファイルのバージョンはWindowsのバージョンと一致すると言います。 Windows 7コンピューターでは、次のようになります。

これは非常に適切な方法ですが、何らかの理由で、まだ代替手段があるため、個人的には好きではありません。
PEBプロセスを分析します
各Windowsプロセスには、それを記述する構造があり、PEBと呼ばれます。 プロセスの開始時に入力され、ダウンロードアドレス、ロードされたモジュールのリスト、コマンドラインパラメーター、およびWindowsのバージョンが含まれます。 以下は、Windowsの実際のバージョンを取得できるモジュールの例です(Delphi 2010 Win32でテスト済み):
unit RealWindowsVerUnit; interface uses Windows; var
作業の速度は瞬時であり、余分なものはありませんが、唯一の文書化されていないPEB構造ですが、ご存知のように、Microsoftは後方互換性について非常に懸念しているため、多くの楽観的な見方で、構造の記述が長い間インターネットをサーフィンしてきたため、すでにMicrosoftで文書化されていると考えられます。
結論
結論は単純です。実際のバージョンを本当に取得する必要がある場合はWMIが最適ですが、軽量なソリューションが必要な場合はPEBをご覧ください。