RustでWindowsのリソースを扱うembed-resourceクレートのメモ。
embed-resourceは、Windowsのリソースファイル(拡張子rc)をコンパイルしてrustcでリンクするクレート(ビルドツール)。
バージョン情報が書かれたrcファイルやダイアログの定義が書かれたrcファイルをコンパイルしてリンクすることが出来る。
(複数のrcファイルを扱うことが出来る)
ビルド時にWindows SDKのrc.exe(またはMinGW64のwindres.exe)が使われるので、インストールしておく必要がある。
〜 [build-dependencies] embed-resource = "3.0.5"
cargo buildによって生成されるexeファイル(やdllファイル)にバージョン情報を埋め込む例。
まず、元となるバージョン情報を記述した、拡張子rcのリソースファイル(テキストファイル)を作成する。
それから、ビルドスクリプトを作成する。
extern crate embed_resource;
fn main() {
embed_resource::compile("versioninfo.rc", embed_resource::NONE)
.manifest_optional()
.unwrap();
}
embed-resourceは、Windows以外で動かしたときには何もしない(エラーにもならない)ので、OSのことは気にしなくていい。
これでビルドすると、生成されるexeファイル(やdllファイル)にバージョン情報が埋め込まれる。
cargo build
生成されたexeファイル(やdllファイル)を右クリックしてプロパティーを選択し、「詳細」タブを表示すると、埋め込まれたバージョン情報が確認できる。
あるいは、PowerShellから以下のコマンドで確認することも出来る。
(Get-ItemProperty .\target\debug\example.exe).VersionInfo | Format-List
rcファイルはテキストファイルなので、その中に書かれているバージョン番号等を変えたい場合は、rcファイル自体を書き換えなければならない。
しかし、バージョン番号は、Rustプロジェクトのバージョンに合わせて自動的に追随させたい。
embed-resourceでは、rcファイルの中をマクロ変数で記述しておき、build.rsでマクロ変数の内容を定義することが出来る。
以下の例では、REPLACE_VERSIONやREPLACE_VERSION_RAWというマクロ変数を使う。(変数名は自分で決める)
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION REPLACE_VERSION_RAW // 0,1,2,0 のような形式
PRODUCTVERSION REPLACE_VERSION_RAW // 0,1,2,0 のような形式
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0" // 英語 + Unicode
BEGIN
VALUE "OriginalFilename", "myapp.exe"
VALUE "FileDescription", "My Example Application"
VALUE "ProductName", "MyExampleApp"
VALUE "Comments", "My Example comment"
VALUE "CompanyName", "hishidama"
VALUE "FileVersion", REPLACE_VERSION // "0.1.2" のような形式
VALUE "ProductVersion", REPLACE_VERSION // "0.1.2" のような形式
VALUE "LegalCopyright", "Copyright 2025 hishidama"
VALUE "LegalTrademarks", "MyExampleApp(TM)"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1200 // 言語ID(0x0409 = 英語), 文字コード(1200 = Unicode)
END
END
ビルドスクリプトでマクロ変数を定義する。
extern crate embed_resource;
fn main() {
embed_resource::compile(
"versioninfo2.rc",
&["REPLACE_VERSION=\"0.1.2\"", "REPLACE_VERSION_RAW=0,1,2,0"],
)
.manifest_optional()
.unwrap();
}
Rustプロジェクトのバージョン(Cargo.tomlの[package]のversion)を元にするには、以下のようにする。
extern crate embed_resource;
fn main() {
let macros = &[
format!("REPLACE_VERSION=\"{}\"", env!("CARGO_PKG_VERSION")),
format!(
"REPLACE_VERSION_RAW={},{},{},0",
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
env!("CARGO_PKG_VERSION_PATCH")
),
];
embed_resource::compile("versioninfo2.rc", macros)
.manifest_optional()
.unwrap();
}