山本ワールド
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バージョンを取得する(VerfyVersionInfo)
概要
Windows上でバージョン情報を取得する方法はいろいろありますが主な方法として以下の3種類の方法が考えられます。
上表のマニフェストはマニフェストにより動作バージョンを明示することを意味します。
マニフェストを指定しない場合、Windows 8.1まで正常な答えが得られました。マニフェストを指定しない場合ではWindows 10ではWindows 8相当の答えが返ってきます。 上表の互換モードはexeファイルのプロパティで互換性で設定できる互換モードです。
このページではVerfyVersionInfo APIについて解説します。
VerfyVersionInfo APIは、OSVERSIONINFOEX構造体に設定したバージョンと実行しているWindowsのバージョンを比較し、指定した条件を満足するか否かを返します。
本プログラムではVerfyVersionInfo 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ファイルのプロパティで互換性で設定できる互換モードです。
このページではVerfyVersionInfo APIについて解説します。
VerfyVersionInfo APIは、OSVERSIONINFOEX構造体に設定したバージョンと実行しているWindowsのバージョンを比較し、指定した条件を満足するか否かを返します。
本プログラムではVerfyVersionInfo 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上)
プログラムソースの概要
_WinMain関数
OSVERSIONINFOEX構造体をZeroMemoryで0に初期化後、dwOSVersionInfoSizeメンバーに構造体サイズをセットします。VerSetConditionMask APIによりどのメンバーを検索対象にするか、比較方法をcmaskに保存します。
maskにどのメンバーを検索対象にするかを指定します。
メジャーバージョンを取得するために、 OSVERSIONINFOEX構造体へのポインタ・取得するメンバーへのポインタ・maskとcmaskを指定してgetVerDword関数を 呼び出し指定メンバーの値を取得します。
VerSetConditionMask APIにより検索条件を合成しgetVerDword関数及びgetVerWord関数を呼び出し順番に値を取得していきます。
必要な値の取得が全部終了した後、文字列化してメッセージボックスで表示します。
getVerDword関数
指定メンバーの32bit値を取得します。マイナーバージョンとそれ以外では値の取得方法を変えています。マイナーバージョンの取得
メンバー変数のポインタとOSVERINFOEX->dwMinorVersionのポインタを比較し一致した場合マイナーバージョンとなります。 マイナーバージョンの場合、OSVERINFOEXのdwMinorVersionメンバーを0から順番に増やしてゆき一致したマイナーバージョンを取得します。マイナーバージョン以外の取得
上位1bitから下位に向ってビット単位で比較をします。 ビット単位の比較をするために、まずsum=0として上位1bitを比較(変数bit_chkとsumを加算した値をOSVERSIONINFOEXのメンバーに設定してVerifyVersionInfo APIを呼び出す)をして Windowsのバージョンがそれ以上(戻り値がTRUEの場合)であればsumにOSVERSIONINFOEXのメンバーに設定した値を代入します。 その後、bit_chkを1bit右シフトし、比較を下位0ビットになるまで比較します。比較が終了したときのsumの値がWindowsバージョンになりますVerSetConditionMask
VerifyVersionInfo APIの検索条件を作成する関数です。 関数のプロトタイプは以下の通りです。ULONGLONG WINAPI VerSetConditionMask(
_In_ ULONGLONG dwlConditionMask,
_In_ DWORD dwTypeBitMask,
_In_ BYTE dwConditionMask
);
dwlConditionMaskは最初に0にしておく必要があります。dwTypeBitMaskは検索対象を指定します。
dwTypeBitMask | メンバー | 取得する項目 |
---|---|---|
VER_BUILDNUMBER | dwBuildNumber | ビルド番号 |
VER_MAJORVERSION | dwMajorVersion | メジャーバージョン |
VER_MINORVERSION | dwMinorVersion | マイナーバージョン |
VER_PLATFORMID | dwPlatformId | プラットフォーム |
VER_PRODUCT_TYPE | wProductType | プロダクトタイプ |
VER_SERVICEPACKMAJOR | wServicePackMajor | サービスパックメジャー |
VER_SERVICEPACKMINOR | wServicePackMinor | サービスパックマイナー |
VER_SUITENAME | wSuiteMask | スイート名 |
Value | Meaning |
---|---|
VER_EQUAL | 実行OS==指定OS |
VER_GREATER | 実行OS>指定OS |
VER_GREATER_EQUAL | 実行OS>=指定OS |
VER_LESS | 実行OS<指定OS |
VER_LESS_EQUAL | 実行OS<=指定OS |
VerifyVersionInfo
比較を実行し結果を返す関数です。比較条件はVerSetConditionMaskで作成します。
指定した比較条件が成立した場合は0以外の値が返り、成立しない場合およびエラーの場合は0が返ります。
以下に実行しているWindowsがWindows 7以上かを判別するコードの例を示します。
なお、Visual C++ 2013ではVersionHelpers.hで定義されている、IsWindows8Point1OrGreater()などを使えば簡単になります。 IsWindows8Point1OrGreater関数は、内部的にメージャーとマイナーバージョンを設定しVerifyVersionInfo APIで比較しているだけです。
VerifyVersionInfo.cpp
#include <windows.h>
#include <tchar.h>
int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPTSTR lpsCmdLine, int nCmdShow){
OSVERSIONINFOEX ver;
ver.dwOSVersionInfoSize = sizeof(ver);
ver.dwMajorVersion = 6;
ver.dwMinorVersion =1;
LONGLONG cmask = 0;
cmask=VerSetConditionMask(cmask, VER_MAJORVERSION, VER_GREATER_EQUAL);
cmask = VerSetConditionMask(cmask, VER_MINORVERSION, VER_GREATER_EQUAL);
BOOL b;
b = VerifyVersionInfo(&ver, VER_MAJORVERSION | VER_MINORVERSION , cmask);
if (b == TRUE){
MessageBox(0, _TEXT("使用しているOSはWindows 7以上です。"), _TEXT("情報"), MB_OK);
}else{
if (GetLastError()==ERROR_OLD_WIN_VERSION)
MessageBox(0, _TEXT("使用しているOSはWindows 7未満です。"), _TEXT("情報"), MB_OK);
else
MessageBox(0, _TEXT("比較に失敗しました。"), _TEXT("エラー"), MB_OK);
}
}
getVerWord関数
getVerDword関数は取得する値が16bitである以外は、getVerWord関数と同じです。プログラムソース
VerifyVersionInfo2.cpp
// VerifyVersionInfo APIを用いてバージョンを取得
// Visual C++ 2005/2008/2013 32/64bit
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したDWORDの値を取得
void getVerDword(OSVERSIONINFOEX* ver, DWORD* dwp, DWORD mask, LONGLONG cmask);
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したWORDの値を取得
void getVerWord(OSVERSIONINFOEX* ver, WORD* wp, DWORD mask, LONGLONG cmask);
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したBYTEの値を取得
void getVerByte(OSVERSIONINFOEX* ver, BYTE* bp, DWORD mask, LONGLONG cmask);
int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPTSTR lpsCmdLine, int nCmdShow){
OSVERSIONINFOEX ver;
ZeroMemory(&ver, sizeof(ver));
ver.dwOSVersionInfoSize = sizeof(ver);
LONGLONG cmask = 0;
DWORD mask;
cmask = VerSetConditionMask(cmask, VER_MAJORVERSION, VER_GREATER_EQUAL);
mask = VER_MAJORVERSION;
getVerDword(&ver, &ver.dwMajorVersion, mask, cmask);
cmask = VerSetConditionMask(cmask, VER_MINORVERSION, VER_GREATER_EQUAL);
mask |= VER_MINORVERSION;
getVerDword(&ver, &ver.dwMinorVersion, mask , cmask);
cmask = VerSetConditionMask(cmask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
mask |= VER_SERVICEPACKMAJOR;
getVerWord(&ver, &ver.wServicePackMajor, mask , cmask);
cmask = VerSetConditionMask(cmask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
mask |= VER_BUILDNUMBER;
getVerDword(&ver, &ver.dwBuildNumber,mask , cmask);
TCHAR buf[64];
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("メジャー%d マイナー%d\nサービスパック%d\nビルド%d"), ver.dwMajorVersion,ver.dwMinorVersion,ver.wServicePackMajor,ver.dwBuildNumber);
MessageBox(0, buf, _TEXT("Windowsバージョン"), MB_OK);
}
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したDWORDの値を取得
void getVerDword(OSVERSIONINFOEX* ver, DWORD* dwp, DWORD mask, LONGLONG cmask){
if ((BYTE*)dwp == (BYTE*)&(ver->dwMinorVersion)){ // マイナーバージョンの検索である
LONGLONG cmask = 0;
cmask = VerSetConditionMask(cmask, VER_MAJORVERSION, VER_EQUAL);
cmask = VerSetConditionMask(cmask, VER_MINORVERSION, VER_EQUAL);
for (int n = 0; n < 65536; n++){
*dwp = n;
BOOL b;
b = VerifyVersionInfo(ver, mask, cmask);
if (b == TRUE)
return;
}
*dwp = 0xffffffff;
return;
}else{
UINT sum = 0;
int bit_max = 15;
UINT bit_chk = 1 << bit_max;
while (0 <= bit_max){
BOOL b;
*dwp = sum | bit_chk;
b = VerifyVersionInfo(ver, mask, cmask);
if (b == TRUE)
sum |= bit_chk;
bit_chk >>= 1;
--bit_max;
}
*dwp = sum;
}
}
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したWORDの値を取得
void getVerWord(OSVERSIONINFOEX* ver, WORD* wp, DWORD mask, LONGLONG cmask){
UINT sum = 0;
int bit_max = 15;
UINT bit_chk = 1 << bit_max;
while (0 <= bit_max){
BOOL b;
*wp = sum + bit_chk;
b = VerifyVersionInfo(ver, mask, cmask);
if (b == TRUE)
sum += bit_chk;
bit_chk >>= 1;
--bit_max;
}
*wp = sum;
}
// VerifyVersionInfo APIを使いOSVERINFOEXの指定したBYTEの値を取得
void getVerByte(OSVERSIONINFOEX* ver, BYTE* bp, DWORD mask, LONGLONG cmask){
UINT sum = 0;
int bit_max = 15;
UINT bit_chk = 1 << bit_max;
while (0 <= bit_max){
BOOL b;
*bp = sum + bit_chk;
b = VerifyVersionInfo(ver, mask, cmask);
if (b == TRUE)
sum += bit_chk;
bit_chk >>= 1;
--bit_max;
}
*bp = sum;
}
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>
ソースファイルと実行ファイルのダウンロード
ダウンロード VerifyVersionInfo.zip(105kByte)
ZIPファイルに含まれるファイル
ZIPファイルに含まれるファイル
VerifyVersionInfo.cpp Windows 7以上を検出するプログラムのC++ソースファイル VerifyVersionInfo.exe Windows 7以上を検出するプログラム manifest.xml Windows 7~Windows 10までの動作環境を指定したマニフェストファイル VerifyVersionInfo2.cpp メジャー・マイナー・サービスパック・ビルド番号を取得するプログラムのC++ソースファイル VerifyVersionInfo2.exe Visual C++ 2013(v120_xp)で上記マニフェストファイルを組み込んで作成した実行ファイル(Windows XP~Windows 10で実行可能) VerifyVersionInfo2_2008.exe Visual C++ 2008で上記マニフェストファイルを組み込んで作成した実行ファイル(Windows 2000~Windows 10で実行可能)
Copyright (C) 2012 山本ワールド All Rights Reserved.