概要

次の3種類のテストプログラムを実行します。
最初の2つのプログラムは自分自身のプログラムのDLLの適用ルールに従ってCOMCTL32.DLLを検索してバージョン情報を取得、 残りはバージョン情報の設定例として実行ファイルを作成し、その実行ファイルのバージョン情報を取得します。

ビジュアルスタイルを指定せずにCOMCTL32.DLLのバージョン情報を取得

追加のマニフェストを指定していないのでビジュアルスタイルは使用できません。
COMCTL32.DLLのバージョン情報を取得してメッセージボックスで表示します。
ソースファイルの中身は次の項のcomctl6と同じです。
Windows7でcomctl5.exeを実行した例です。

ビジュアルスタイルを指定してCOMCTL32.DLLのバージョン情報を取得

Side-by-Sideを使用し マニフェストファイルにCOMCTL32.DLLのバージョン6を指定し、追加のマニフェストファイルとして指定しています。
COMCTL32.DLLのバージョン情報を取得してメッセージボックスで表示します。
Windows7でcomctl6.exeを実行した例です。

リソースファイルへのバージョン情報の埋め込み例とバージョン情報の取得の例

versuport.exeに埋め込まれているバージョン情報をfilever2.exeで表示します。
versupoer.cppがversuport.exeを作成するためのC++ソースファイル、filever2.cppがfilever2.exeを作成するためのC++ソースファイルです。
filever2.exeを実行するとversupoer.exeのバージョン情報を取得し表示します。
Windows7でfilever2.exeを実行した例です。

参考までにエクスプローラでversuport.exeのプロパティを表示した例を示します。

versuport.exeのバージョン情報をリソースファイルである resource.rcの以下の行でバージョン番号を設定しています。
FILEVERSION              1, 2, 3,9

テスト環境

コンパイラ

Visual C++ 2008 Standard 32/64bit
Visual C++ 2013 Express 32/64bit

プロジェクトの作成

Win32プロジェクト Windowsアプリケーション

実行環境

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

プログラムソースの概要

comctl6.cpp・comctl5.cpp・filever2.cpp

この3つのソースファイルの違いは、バージョン取得するファイル名の違いだけです。

comctl6.cpp・comctl5.cpp

TCHAR* path = TEXT("COMCTL32.DLL");

filever2.cpp

TCHAR* path = TEXT("versuport.exe");

_tWinMain関数

get_file_version関数を呼び出しバージョン情報を配列verに取得します。
正常に取得できた場合は、 _stprintf_s関数によりバージョン値を文字列化してMessageBox APIを呼び出して表示します。
正常に取得できなかった場合は、エラーを表示します。

get_file_version関数

GetFileVersionInfoSize APIによりバージョン情報のバイト数を調べます。
GetFileVersionInfo APIはファイルのバージョンが取得できる場合はバージョン情報のバイト数、 取得できない場合は0が返ります。
0が返ってきた場合は、FALSEを戻り値として関数を終了します。
取得されたバイト数のメモリをnew演算子により確保します。
GetFileVersionInfo APIにより先ほど確保したメモリにバージョン情報を取得します。
バージョン情報が取得できなかった場合は、メモリを開放し関数を戻り値をFALSEにセットし関数を終了します。
VerQueryValue APIの第1引数に先ほど取得した情報のうちVS_FIXEDFILEINFO構造体へのポインタを取得します。
第1引数にGetFileVersionInfo APIで取得した情報、第2引数は構造体に情報を取得、第3引数に構造体へのポインタ、 第4引数にDWORD型へのポインタを指定して呼び出すとVS_FIXEDFILEINFO構造体へのポインタが返されます。
VerQueryValue APIが0以外を返した場合は、バージョン情報が使用できます。
バージョン情報が取得できなかった場合は、メモリを開放し関数を戻り値をFALSEにセットし関数を終了します。
バージョン情報が取得できた場合は、 構造体のメージャーバージョンとマイナーバージョンを示すメンバ変数からバージョン情報を取り出し、ver配列に格納します。
メモリを開放して戻り値をTRUEにセットして関数を終了します。

プログラムソース

comctl6.cpp

comctl6.cpp・comctl5.cpp・filever2.cppはポインタに代入するファイル名の違いのみなので、comctl6.cppのみ示します。
これらのファイルの違いは、プログラムソースの概要を参照してください。
//       COMCTL32.DLLのバージョンを表示する
//      Visual C++ 2008/2013    32/64bit

#include <windows.h>
#include <winver.h>
#include <stdio.h>
#include <tchar.h>

#pragma comment(lib,"version.lib")

//      ファイルのバージョンを表示する
BOOL get_file_version(TCHAR* path, int ver[4]);

int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, TCHAR* lpsCmdLine, int nCmdShow){
        int ver[4];
        TCHAR buf[64];

        TCHAR* path = TEXT("COMCTL32.DLL");

        if (get_file_version(path, ver) == TRUE){
                _stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), TEXT("Version %i,%i,%i,%i"), ver[0], ver[1], ver[2], ver[3]);
                MessageBox(0, buf, path, MB_OK);
        }else{
                MessageBox(0, _TEXT("バージョン情報の取得に失敗しました。"), 0, MB_OK);
        }
        return 0;
}

//      ファイルのバージョンを表示する

BOOL get_file_version(TCHAR* path, int ver[4]){
        VS_FIXEDFILEINFO* v;
        DWORD dwZero = 0;
        UINT len;
        DWORD sz = GetFileVersionInfoSize(path, &dwZero);
        if (sz){
                void* buf = new char[sz];
                GetFileVersionInfo(path, dwZero, sz, buf);

                if (VerQueryValue(buf, TEXT("\\"), (LPVOID*)&v, &len)){
                        ver[0] = int(HIWORD(v->dwFileVersionMS));
                        ver[1] = int(LOWORD(v->dwFileVersionMS));
                        ver[2] = int(HIWORD(v->dwFileVersionLS));
                        ver[3] = int(LOWORD(v->dwFileVersionLS));
                        delete buf;
                        return TRUE;
                }else{
                        delete buf;
                        return FALSE;
                }
        }else
                return FALSE;
}

versuport.exe

versuport.exeを作成するためには、versuport.cppとバージョン情報を設定するリソースファイルresource.rcが必要です。

versuport.cpp

// バージョン情報テスト
// Visual C++ 2013 32/64bit

#include <windows.h>
#include <tchar.h>

int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, TCHAR* lpsCmdLine, int nCmdShow){
        MessageBox(0, _TEXT("バージョン情報"), _TEXT("テスト"), MB_OK);
        return 0;
}

resource.rc

#include <windows.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION             1, 2, 3,9
PRODUCTVERSION  5, 6, 7, 8
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "Comments", "バージョン情報テスト\0"
            VALUE "CompanyName","バーチャル\0"
            VALUE "FileDescription", "バージョン情報テスト\0"
            VALUE "FileVersion",  "1, 2, 3, 4\0"
            VALUE "InternalName", "\0"
            VALUE "LegalCopyright","Copyright (C) 2012/03/04" 
            VALUE "OriginalFilename", "versuport.exe\0"
            VALUE "ProductName", "バージョン情報テスト"
            VALUE "ProductVersion",  "5, 6, 7, 8\0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation",0x0411, 0x03A4 
    END
END

ソースファイルと実行ファイルのダウンロード

ダウンロード filever.zip(163kByte)
ZIPファイルに含まれるファイル
│  comctl5.exe
│  comctl6.exe
│  filever2.exe
│  versuport.exe
│  
├─comctl5
│      comctl5.cpp
│      
├─comctl6
│      comctl6.cpp
│      YourApp.manifest
│      YourApp64.manifest
│      
├─filever2
│      filever2.cpp
│      
└─versuport
        resource.rc
        versuport.cpp