山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他Windowsバージョンを取得する(RtlGetVersion)
概要
Windows上でバージョン情報を取得する方法はいろいろありますが主な方法として以下の3種類の方法が考えられます。
上表のマニフェストはマニフェストにより動作バージョンを明示することを意味します。
マニフェストを指定しない場合、Windows 8.1まで正常な答えが得られました。マニフェストを指定しない場合ではWindows 10ではWindows 8相当の答えが返ってきます。 上表の互換モードはexeファイルのプロパティで互換性で設定できる互換モードです。
このページではRtlGetVersion APIについて解説します。
以下に本プログラムを各Windowsで実行した例を示します。
Windows 2000 Service Pack 4 Windows XP Service Pack 3 Windows Vista Service Pack 2 Windows 7 Service Pack 1 Windows 8.1 Windows 10
API | マニフェスト | 互換モード | 備考 |
---|---|---|---|
GetVersionEx API | 8.1以上を取得時には指定が必要 | 依存 | Windows 95以上又はWindows NT 3.5以上で実行可能 Windows 8.1以降は非推奨だが10でも使用可能 |
VerfyVersionInfo API | 10以上を取得時には指定が必要 | 非依存 | 自身のWindowsのバージョンに対して上位か同一か下位といった判定しかできない Windows 2000以上でのみ実行可能 |
RtlGetVersion API | 非依存 | 依存 | DDK等をインストールしていない場合、ヘッダーファイルおよびライブラリが無い Windows 2000以上でのみ実行可能 |
マニフェストを指定しない場合、Windows 8.1まで正常な答えが得られました。マニフェストを指定しない場合ではWindows 10ではWindows 8相当の答えが返ってきます。 上表の互換モードはexeファイルのプロパティで互換性で設定できる互換モードです。
このページではRtlGetVersion APIについて解説します。
以下に本プログラムを各Windowsで実行した例を示します。
Windows 2000 Service Pack 4 Windows XP Service Pack 3 Windows Vista Service Pack 2 Windows 7 Service Pack 1 Windows 8.1 Windows 10
Windowsの内部バージョン一覧
Windowsの内部バージョン一覧を以下に示します。
メンバー | NT 3.1 Workstation |
NT 3.5 Workstation |
NT 3.51 Workstation |
---|---|---|---|
dwMajorVersion | 3 | 3 | 3 |
dwMinorVersion | 1 | 5 | 51 |
wProductType | 1 | 1 | 1 |
メンバー | NT 4.0 Workstation |
95 | 98 | 98SE | me |
---|---|---|---|---|---|
dwMajorVersion | 4 | 4 | 4 | 4 | 4 |
dwMinorVersion | 0 | 0 | 10 | 10 | 90 |
wProductType | 1 | 0 | 0 | 0 | 0 |
メンバー | 2000 | XP | 2003R2 |
---|---|---|---|
dwMajorVersion | 5 | 5 | 5 |
dwMinorVersion | 0 | 1 | 2 |
wProductType | 1 | 1 | 3 |
メンバー | Vista | 7 | 2008R2 | 8 | 8.1 | 2012 | 2012R2 |
---|---|---|---|---|---|---|---|
dwMajorVersion | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
dwMinorVersion | 0 | 1 | 1 | 2 | 3 | 2 | 3 |
wProductType | 1 | 1 | 3 | 1 | 1 | 3 | 3 |
メンバー | 10 |
---|---|
dwMajorVersion | 10 |
dwMinorVersion | 0 |
wProductType | 1 |
テスト環境
コンパイラ
Visual C++ 2008 Standard 32/64bitVisual C++ 2013 Express 32/64bit
プロジェクトの作成
Win32プロジェクト Windowsアプリケーション実行環境
Windows 10 Pro 64bit(Virtual Box上)Windows 8.1 Enterprise 64bit
Windows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit
Windows 2000 Professional Service Pack 4(Virtual Box上)
プログラムソースの概要
RtlGetVersion APIはDDK等をインストールしないとヘッダーファイルやライブラリが使えません。またANSI版が存在しません。
上記の煩わしさを解消するためにGetVersion2関数を作成しました。
GetProcAddress APIによりntdll.dllのRtlGetVersion APIのポインタを取得します。
RtlGetVersion APIを呼び出し、バージョン情報をOSVERSIONINFOEXW構造体に取得します。
マルチバイトでコンパイルする場合は、OSVERSIONINFOEXW構造体のメンバーをOSVERSIONINFOEXAのメンバーにコピーします。
UNICODE文字列が保存されているOSVERSIONINFOEXW構造体のszCSDVersionメンバーの文字列を ANSIに変換してOSVERSIONINFOEXA構造体のszCSDVersionメンバーに代入します。
最後にFreeLibrary APIでntdll.dllを解放します。
上記の煩わしさを解消するためにGetVersion2関数を作成しました。
_tWinMain
GetVersion2関数を呼び出し、OSVERSIONINFOEX構造体にバージョン情報を取得しメッセージボックスに結果を表示します。GetVersion2
LoadLibrary APIによりntdll.dllを読み込みます。GetProcAddress APIによりntdll.dllのRtlGetVersion APIのポインタを取得します。
RtlGetVersion APIを呼び出し、バージョン情報をOSVERSIONINFOEXW構造体に取得します。
マルチバイトでコンパイルする場合は、OSVERSIONINFOEXW構造体のメンバーをOSVERSIONINFOEXAのメンバーにコピーします。
UNICODE文字列が保存されているOSVERSIONINFOEXW構造体のszCSDVersionメンバーの文字列を ANSIに変換してOSVERSIONINFOEXA構造体のszCSDVersionメンバーに代入します。
最後にFreeLibrary APIでntdll.dllを解放します。
プログラムソース
RtlGetVersion.cpp
// RtlGetVersion APIを使用してWindowsのバージョン番号を取得する
// RtlGetVersion APIをサポートしていない場合は、GetVersionEx APIを使用する
// Visual C++ 2005/2008/2013 Unicode/マルチバイト
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
// DLL内の関数へのポインタ型を定義
typedef void (WINAPI *RtlGetVersion_FUNC)(OSVERSIONINFOEXW*);
BOOL GetVersion2(OSVERSIONINFOEX* os);
int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPTSTR lpsCmdLine, int nCmdShow){
TCHAR buf[256];
OSVERSIONINFOEX os;
if (GetVersion2(&os) == TRUE){
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("MajorVersion %d\nMinorVersion %d\nBuild %d\n"),
os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber);
MessageBox(0, buf, _TEXT("Windows Version"), MB_OK);
}
else{
MessageBox(0, _TEXT("RtlGetVersion APIがサポートされていません"), _TEXT("Error"), MB_OK);
}
return (int)0;
}
BOOL GetVersion2(OSVERSIONINFOEX* os){
HMODULE hMod;
RtlGetVersion_FUNC func;
#ifdef UNICODE
OSVERSIONINFOEXW* osw = os;
#else
OSVERSIONINFOEXW o;
OSVERSIONINFOEXW* osw = &o;
#endif
hMod = LoadLibrary(TEXT("ntdll.dll"));
if (hMod){
func = (RtlGetVersion_FUNC)GetProcAddress(hMod, "RtlGetVersion");
if (func == 0){
FreeLibrary(hMod);
return FALSE;
}
ZeroMemory(osw, sizeof(*osw));
osw->dwOSVersionInfoSize = sizeof(*osw);
func(osw);
#ifndef UNICODE
os->dwBuildNumber = osw->dwBuildNumber;
os->dwMajorVersion = osw->dwMajorVersion;
os->dwMinorVersion = osw->dwMinorVersion;
os->dwPlatformId = osw->dwPlatformId;
os->dwOSVersionInfoSize = sizeof(*os);
DWORD sz = sizeof(os->szCSDVersion);
WCHAR* src = osw->szCSDVersion;
unsigned char* dtc = (unsigned char*)os->szCSDVersion;
while (*src)
*dtc++ = (unsigned char)*src++;
*dtc = '\0';
#endif
}
else
return FALSE;
FreeLibrary(hMod);
return TRUE;
}
manifest.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
ソースファイルと実行ファイルのダウンロード
ダウンロード RtlGetVersion.zip(67.7kByte)
ZIPファイルに含まれるファイル
ZIPファイルに含まれるファイル
RtlGetVersion.cpp C++ソースファイル RtlGetVersion.exe Visual C++ 2013(v120_xp)で作成した実行ファイル(Windows XP~Windows 10で実行可能) RtlGetVersion2008.exe Visual C++ 2008で上作成した実行ファイル(Windows 2000~Windows 10で実行可能)
Copyright (C) 2012 山本ワールド All Rights Reserved.