実行形式のバージョン情報を取得

 これもさほど難しくない奴です。使うAPIは次の3つくらいです。

GetFileVersionInfoSize  バージョン情報リソースのサイズを調べる
GetFileVersionInfo      バージョン情報リソースをメモリに..
VerQueryValue           メモリに読み込んだバージョン情報リソースから値を取得

◆取りあえずバージョン番号を取得

「コメント」や「著作権情報」の取得は取りあえずおいといて、番号を取得します。

char szFile[] = "Shell32.dll"; // 対象ファイル名
ULONG tem; // 値自体は使わない
VS_FIXEDFILEINFO vffi; // バージョン情報を受け取る構造体

UINT size = GetFileVersionInfoSize(szFile,&tem);
size += 5; // なんとなく5バイト余分に確保
vbuf = new byte[size];

if (GetFileVersionInfo(szFile, 0, size, vbuf))
{
    void *buf;
    VerQueryValue(vbuf,TEXT("\\"),&buf,&size);         // バージョンを取得
    CopyMemory( &vffi, buf, sizeof(VS_FIXEDFILEINFO)); //コピー
}

// ★ vffi 構造体にいろいろ入っているのでそれを必要に応じてコピー
// ★ コメントなど取得するときもこの中で取得する

delete [] vbuf; // メモリ解放

取りあえずこれだけ。コメントを追っていけば簡単に理解できるはずです(ちょっと省略しすぎと言う説も)

◆コメントやら著作権情報やらを取得

上と同じ手順で読み出し のあるところにコードを挿入していきます。手順は
 1.バージョン情報のロケールIDを取得
 2.第2引数に目的の値を示す文字列を入れてVerQueryValueを呼ぶ
とこれだけです。まず1のロケールIDの取得は簡単です。

char *buf = NULL;
int iLocale = 0;
VerQueryValue(vbuf, "\\VarFileInfo\\Translation", (void**)&buf, &size); // ロケールの取得
CopyMemory(&i, buf, sizeof(int));

とまぁこんなもんでしょうか。もっとスマートなやり方があるような気がしますが(CopyMemoryらへん)気にせず。

あとは取得するのみです。

char szName[] = "FileVersion"; // 取得する値を指定する文字列
char textbuf[200];
// ↓取得するために使う文字列を作る
wsprintf(textbuf, "\\StringFileInfo\\%04X%04X\\%s", LOWORD(iLocale), HIWORD(iLocale), szName);
VerQueryValue(vbuf,textbuf,(void**)&buf,&size);
// ◆ bufを char* にキャストすれば文字列として使える。
// ◆ 要求した値が存在しない場合は変なのが返るので、
// ◆ 1文字目がASCIIコードで20以上あるか調べた方がよい(Undocument)
// ◆ vbufを解放すれば使えなくなるので早めにコピーした方がよい

szNameに指定できる文字列は以下の通りです。
CompanyName 会社名
FileDescription 説明
FileVersion ファイル・バージョン
InternalName 内部名
LegalCopyright 著作権
OriginalFileName 正式ファイル名
ProductName 製品名
ProductVersion 製品バージョン
Comments コメント
LegalTrademarks 商標
PrivateBuild プライベート・ビルド情報
SpecialBuild スペシャル・ビルド情報

なんか見にくいtipsになってしまいましたね。絶対に全部いると言うわけではないのでこういう風になってしまったのですが、全部まとめてやればよかったかなとか思ってます……けどもう遅いです(ぉ。まぁ、数字の方が扱いやすいので一番上の奴くらいで良いでしょう。


記事の無断転載は禁止です。 Copyright 1999-2001 Runan. All Rights Reserved.