Pythonで作成したexeにファイルバージョン情報を追加する方法
2020年08月26日に全面的に書き直しました。
はじめに
プログラミング言語Python(PyInstallerやPy2exe等)で作成したexeファイル(実行ファイル)に対してバージョン情報を追加したい、という話です。
確認環境
環境・前提は以下になります。
- Windows 10 Home
- Python 3.7~3.8
- PyInstaller 3.6~4.0
- Anaconda 使用していません
ファイルバージョン情報とは
Windowsのexeファイルを右クリックした場合、通常は以下のようなファイル情報が表示されます。
しかし、Python(PyInstallerやPy2exe)でexe化したファイルについては、以下のようにバージョンなどの情報が設定されていません。
私がここの「ファイルの説明」「ファイルバージョン」等の情報について追加(追記・設定)した方法について記載します。
これらの情報、正式名称は何ていうのでしょうね。ファイルリソース?バージョンリソース?
以下「バージョン情報」と記載します。
Visual Studio等のIDEを使えば簡単なことなのですが、IDEを使わないとこんなことが意外と難しく。
前置き
結論を先に話すと、PyInstallerでもできましたが「ResourceHacker.exe」というツールを使いました。
インターネットで調べた感じだと、PyInstallerでもPy2exeでもexe作成時にバージョン情報を設定できるらしいのですが、Py2exeについてはとりあえず私にはできませんでした。PyInstallerについては使い勝手が悪い感じです。試行錯誤した内容については最後に記載します。
ここを読んでくださっている皆さまもおそらく目的は「バージョン情報を追加すること」であり、手段は問わないはずです。PyInstallerやPy2exeに固執しないことをお勧めします。
私は以下のサイトを参考に作業しました。
バージョン情報を設定する2つの方法
exeファイルにファイルバージョンを設定(追加)する方法として、ここでは以下の2つの方法に触れます。
- ResourceHackerで設定
- PyInstallerで設定
個人的には断然、前者の「ResourceHacker」をお薦めします。
その理由は「exeを作ったあとでも編集できること」です。
逆の言い方をすればPyInstallerでは、ファイルバージョン情報を編集するためにexeを作り直す必要があるということです。
まず、便利なResource Hackerについて説明します。
Resource Hackerでバージョン情報を追加
以下のサイトからResource Hackerというツールをダウンロードします。
私はページ一番下の「Download version 5.1.7:」の「ZIP install (3.0MB)」をダウンロードしました。(個人的には「install」と書かれるとなんだか怖いです。)
解凍して「ResourceHacker.exe」を実行します。↓
この画面上に、バージョン情報を設定したいexeファイルをドラッグ&ドロップします。↓
↑ここではファイル情報を記載すべき「Version Info」が左ビューにありません。
そこで、以下のどちらかを行います。
- バージョン情報を別exeからコピーする
- .resファイルを読み込ませる
基本的に方法は同じです。
メニューの[Action]から[Add from Resource file(*.res, *.mui, *.dll, *.exe)...]を選択し、
バージョン情報のベースとする「.exe」か「.res」ファイルを選択します。
「言語=日本語(日本)」としたい場合は、すでにそのように設定されている「.exe」か「.res」を使用してください。
次に表示される「Import Resources...」画面で「Version Info」にチェックをつけて「Import」をクリックします。↓
そうすると左ビューに「Version Info」が追加され、選択すると右ビューにバージョン情報が表示されます。
右ビューで編集可能です。
ちなみにこのツール、ちょっとクセがあり、右ビューで修正しても、左ビューで違う項目を選び直したりしないと修正が反映できません。(Saveができない)
修正を反映したい場合は以下の画面を表示して「Compile」を選択してください。
これで変更内容が保存されます。(この画面が表示されていない場合は更新されていないと思われます。)
メニューの[Save As]ボタンをクリックして、exeファイルを保存します。
バージョン情報の保存(=プロジェクトの保存みたいなもの?)とexeの出力が別なのかな?
できあがったexeファイルを右クリックして確認し、終了です。
ファイルバージョンが書き換わらない場合は、右ビューの一番上の方の「FILEVERSION」という記載部分を確認してみてください。
ちなみにですが、この作業を行ってもexeファイルの更新日時は更新されません。
Resource Hackerでのバージョン情報の追加については以上です。
★後程、ここにバージョン情報のベースにできるexeをアップします。★
PyInstallerでバージョン情報を追加
PyInstallerでのバージョン情報の追加方法について。
以下のコマンドで、PyInstallerでのexe作成時にバージョン情報を設定できます。
pyinstaller sample.py --version-file バージョン情報ファイル名
(PyInstallerというかPythonのバージョンやシステムビット数を指定したい場合は「pyinstaller」の部分をpyinstaller.exeのフルパスに置き換えてください)
ここでいう「バージョン情報ファイル名」というのは、「.exe」でも「.rc」でも「.res」でもありません。
UTF-8の「.txt」です。
以下がサンプルです。
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(1, 3, 5, 7),
prodvers=(1, 9, 9, 9),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'041104B0',
[StringStruct(u'CompanyName', u'会社名を入力'),
StringStruct(u'FileDescription', u'ファイルの説明を入力'),
StringStruct(u'FileVersion', u'1.50.06'),
StringStruct(u'InternalName', u'InternalNameを入力(非表示)'),
StringStruct(u'LegalCopyright', u'コピーライトを入力'),
StringStruct(u'OriginalFilename', u'オリジナルファイル名を入力'),
StringStruct(u'ProductName', u'製品名を入力'),
StringStruct(u'ProductVersion', u'2.34.56')])
]),
VarFileInfo([VarStruct(u'Translation', [1041, 1200])])
]
)
このファイルを使用すると以下のようになります。
このバージョン情報ファイルは後述の「pyi-grab_version」コマンドでも作成できます。
ちなみに「バージョン情報ファイル名」について私が試したところでは
「.exe」を指定すると
UnicodeDecodeError: 'utf-8' codec can't decode byte~
「.rc」を指定すると
File "<string>", line 1
VS_VERSION_INFO VERSIONINFO
^
SyntaxError: invalid syntax
「.res」を指定すると
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 8: invalid start byte
となりました。
(未確認ですが、「-r」オプションを使用すべきなのだと思います。)
PyInstallerで設定したバージョン情報についてももちろんResource Hackerで編集可能です。ただし、「言語」については変更できません。
バージョン情報の設定の仕方については以上です。
補足
PyInstallerの変更ログ(PyInstaller 3.6のところ)に以下のような記載がありました。
(Windows)VSVersionInfoをEXEのバージョン引数として再び使用できるようにします。(#4381、#4539)
3.6未満ではバージョン情報を追加できなかった不具合があったけど、3.6では直っているということでしょうか。
3.6以降では気にすることではない?
以下、試行錯誤した内容やその他について記載します。
PyInstallerのpy-grab_version.py
PyInstallerでのバージョン情報追加については、当初(ちょっと古いですが)以下のブログを参考にやってみました。
PyInstallerで作ったWindowsアプリでバージョンを表示させたい(Version Resource Fileの作りかた)
上記のブログを読んだ感じだと、バージョンリソースファイルというものの設計?がとても複雑そうで、「1から作成するのは無理だから、他のexeファイルから持ってきたバージョンリソースファイルを編集し、それを自作したexeに埋め込みましょう」という話です。
だとするとPyInstallerでバージョン情報を(編集・訂正ではなく)作成・追加することが困難なのも納得ですし、他の方法でもきっと難しいのでしょう。
で、実際にやってみると、というかその前段階として
PyInstallerインストール済みの自分のマシンに、そもそも「py-grab_version.py」というスクリプトが存在しませんでした。
上記のブログが2014年のものでしたので、おそらく当時のPyInstallerのパッケージには「py-grab_version.py」が入っていたのでしょう。
2020年08月現在、PyInstaller 3.6~4.0には「py-grab_version.py」は入っていません。
「file_version_info.txt」は、自作するか別のツールで抽出する必要がありそうです。(↑に書いたUTF-8の「.txt」をコピペ+編集でもOKです。)
入っていませんが、↓のコマンドが使えました。
py-grab_version.pyからpyi-grab_versionへ
上で「py-grab_version.pyがなくなった」と書きましたが、その代替手段なのか「pyi-grab_version」というコマンドが使用できます。
pyi-grab_version sample.exe
を実行すると、sample.exeのバージョン情報をカレントディレクトリに「file_version_info.txt」として出力します。
この「file_version_info.txt」を編集してから
pyinstaller sample.py --version-file file_version_info.txt
とすることでsample.exeにfile_version_info.txtの情報を付加できます。
Py2exeでバージョン情報を追加できず
「py2exe」の話です。
インターネットの情報を見ていると、Py2exeで使用するsetup.pyのsetup()の中に「name=’hoge’」「version=’hoge’」「description=’hoge’」的な記載をすればバージョン情報を設定できるように読めるのですが、私はできませんでした。
内容、項目などいろいろ試してみたのですが…
参考にしたサイトは以下です。
- QuickIRを py2exeでWindowsのEXEファイルにする(2)
- python : py2exe ListOfOptions
- py2exeとsetuptoolsの連携
- py2exeでバージョン番号などを付加する場合の注意
- 2. setup スクリプトを書く
基本的に古い情報ですが、皆さんできているんでしょうかね。
「以前はできたけど今はできない」ということなのでしょうか、私の作業がおかしいのでしょうか。
ちなみに私が試したバージョンは以下になります。
- Python 3.7~3.8
- Py2exe 0.9.2.2~0.9.3.2
Python 3.7に対応しているというPy2exeの0.9.3.2を、以下のブログを参考にpipからではなくダウンロードしてインストールしました。
「.res」ファイルの作り方
バージョン情報の追加とは直接関係ありませんが、ツールを使うことで「.rc」ファイルから「.res」ファイルが作成できますので方法を説明します。
Resource Compiler - A free resource compiler (GoRC.exe)というツール使用します。
The Go tools for Windows + Assembler
の
Download GoRC version 1.0.2.1 (with documentation 63K)
というリンクからダウンロードしました。
まず、以下のような内容の「Resources.rc」的な名前のファイルをエディタで作成します。
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "CompanyName", "会社名を入力\0"
VALUE "FileDescription", "説明を入力\0"
VALUE "FileVersion", "1.0.0.0\0"
VALUE "LegalCopyright", "コピーライトを入力\0"
VALUE "OriginalFilename", "ファイル名を入力\0"
VALUE "ProductName", "製品名を入力\0"
VALUE "ProductVersion", "1.0.0.0\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}
作成した「Resources.rc」を「GoRC.exe」のアイコンにドラッグ&ドロップすると「Resources.rc」と同じフォルダに「Resources.res」というファイルができます。
まとめ
- Py2exeではファイルバージョン情報を付加できませんでした
- PyInstallerでファイルバージョン情報を付加できましたが使い勝手がよくありません
- ファイルバージョン情報の設定・編集にはResourceHackerが最適です
以上。
後記
最後までお読みくださりありがとうございます。
こんなに更新したのに、現在はほぼ誰も見ていないゴミカスクズ無価値ブログです。
よければ(はてな)ブックマークや拡散をお願いいたします。
更新の原動力として励ましが欲しいのです…<(_ _)>
ディスカッション
コメント一覧
はじめまして
リソースハッカーの使い方でご教授頂ければ幸いです
アイコンのファイルサイズと更新日時の変更方法がわかりません。
ご教授頂ければ幸いです
何卒宜しくお願い致します
えりたまSpecial様、コメントありがとうございます。
リソースハッカー、しばらく使っておらず、状況が思い出せない状態です。お力になれず申し訳ありません。また、コメント返信に気づかず数ヶ月が経ってしまい、こちらも申し訳ありません。(なんでコメントの通知が来ないんだろう…)