После компиляции приложения командной строки Rust в двоичный файл *.exe в Windows я проверил детали двоичного файла, и они в основном пусты:
Есть ли способ добавить file description, file version, Product name, Product version через файл Cargo.toml в скомпилированный exe-файл?
Обновлять:
Я использовал winresource и все работало согласно инструкции библиотеки.
В Cargo.toml я добавил ссылку на скрипт сборки в разделе build-dependencies:
[build-dependencies]
winresource = "0.1.14"
И мой скрипт build.rs выглядит так:
extern crate winresource;
fn main() {
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "windows" {
let mut res = winresource::WindowsResource::new();
res.set_icon("images/aws_client.ico");
res.compile().unwrap();
}
}
Наконец, я добавил небольшой раздел в Cargo.toml, подобный этому:
[package.metadata.winresource]
ProductName = "Command Line AWS Client"
LegalCopyright = "Copyright © 2022"
Результирующие свойства файла выглядят следующим образом:

Информационные данные исполняемого файла Windows хранятся в виде ресурса в разделе .rsrc программы. Компилятор rustc не создаст такой раздел, это то же самое, что и другие родные компиляторы Windows: gcc, clang или MS cl этого не сделают.
Вместо этого вам нужно записать данные ресурса на специальном языке (файл *.rc) и скомпилировать его с помощью компилятора ресурсов. Это создаст объектный файл, который вы можете связать со своей программой.
Естественно, для этого есть ящик! Вы можете попробовать winresource (который недавно был разветвлен из winres, который кажется неуправляемым).
Или вы можете собрать ресурсы самостоятельно. Есть еще один крейт под названием windres, который найдет для вас компилятор ресурсов. Вы можете добавить это в свои сборки-зависимости, а затем написать build.rs что-то вроде:
fn main() -> std::io::Result<()> {
println!("cargo:rerun-if-changed=build.rs");
let target_os = std::env::var("CARGO_CFG_TARGET_OS");
if target_os.as_deref() == Ok("windows") {
let name = env!("CARGO_PKG_NAME");
let version = env!("CARGO_PKG_VERSION");
let mut sv = version.split('.').collect::<Vec<_>>();
while sv.len() < 4 {
sv.push("0");
}
let file_version = format!("{}, {}, {}, {}", sv[0], sv[1], sv[2], sv[3]);
windres::Build::new()
.define("THE_PROJECT", Some(format!(r#""{name}""#).as_str()))
.define("THE_VERSION", Some(format!(r#""{version}""#).as_str()))
.define("THE_FILEVERSION", Some(file_version.as_str()))
.compile("res/resource.rc")?;
for entry in std::fs::read_dir("res")? {
let entry = entry?;
println!("cargo:rerun-if-changed = {}", entry.path().display());
}
}
Ok(())
}
Затем в файле res/resource.rc:
#pragma code_page(65001)
1 VERSIONINFO
FILEVERSION THE_FILEVERSION
PRODUCTVERSION THE_FILEVERSION
FILEFLAGSMASK 0x0000003Fl //VS_FFI_FILEFLAGSMASK
FILEFLAGS 0x0
FILEOS 0x00040004l //VOS_NT_WINDOWS32
FILETYPE 0x00000001l //VFT_APP
FILESUBTYPE 0x00000000l //VFT2_UNKNOWN
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "FileDescription", THE_PROJECT
VALUE "FileVersion", THE_VERSION
VALUE "ProductVersion", THE_VERSION
VALUE "ProductName", THE_PROJECT
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 0x4B0
}
}
1 ICON "res/the_icon.ico"
Несколько замечаний по этому файлу:
#pragma code_page объявляет этот файл в кодировке UTF-8. Существуют и другие значения кодовых страниц, но единственно правильным является UTF-8.THE_FILEVERSION должно быть ровно 4 целых числа, разделенных запятыми. THE_VERSION однако это свободная строка. Я использую скрипт build.rs для конвертации.0x00000001l) эквивалентны этой константе в комментарии. Я использую константу, чтобы не включать файл winver.h, который вызывает проблемы в некоторых средах.FILEVERSION, представляют собой фиксированную информацию о версии, а блок StringFileInfo содержит список локализованных строк ключ-значение. Есть много предопределенных , и вы даже можете создать свой собственный. Если вы используете локализованные строки, вам также понадобится блок VarFileInfo, объявляющий сам язык. Паре целых чисел 0x409, 0x4B0 соответствует строка "040904B0", что, по-моему, означает "английский, Unicode" ( здесь — список кодов).Возможно, вам придется немного поэкспериментировать, чтобы получить желаемую версию, но все части уже есть.