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(); }