🌀

Pythonが入ってないPCで実行ファイルを動かす -cx_Freezeを使ってexeファイルに変換してインストーラーを作成する-

2022/08/05に公開

はじめに

自身で作成したPythonの実行ファイルをPythonをPCにインストールしていない方々へ配布する為にcx_Freezeを使ってexeファイルのインストーラーを作成したので、自信もメモも兼ねて作成方法を紹介します。

公式はこちら↓
https://cx-freeze.readthedocs.io/en/latest/setup_script.html

実行環境

  • Windows10
  • Python 3.9.6
  • 仮想環境 venv

バージョン

cx_Freezeのバージョンと対応しているPythonのバージョンになります。

cx_Freeze version Python version Status
cx_Freeze 6.9 and 6.10 Python 3.6 to 3.10 supported
cx_Freeze 6.4 to 6.8 Python 3.6 to 3.9 supported
cx_Freeze 6.2, 6.3 Python 3.5.2 to 3.8 unsupported
cx_Freeze 6.1 Python 3.5.0 to 3.8 unsupported
cx_Freeze 6.0 Python 3.5.0 to 3.7 unsupported
cx_Freeze 5.1.1 Python 2.7 unsupported

Pythonが入っていないPCに配布するのが目的ですので、使用する先のPythonのversionは考える必要はないかと思われます。なのでPython3.6以上でcx_Freezeの最新版をインストールしてbuildするのがおすすめです。

既にPython3.5以下での環境で作成済みの場合は対応しているcx_Freezeのインストールをお願いします。

インストール

下記コマンドを実行してCX_Freezeをインストールします。

PowerShell
pip install cx_Freeze

公式では仮想環境でインストールする場合は引数--upgradeを入れるとなっていますが私はvenvの仮想環境ですが引数なしでもインストールできました。
バージョンを指定する場合は指定してインストールします。
(例) cx_Freeze=6.1

準備

まずはPythonの実行ファイルを用意します。

myApp.py
import tkinter as tk

root = tk.Tk()
root.title("MyApp")
root.geometry("300x100")

frame = tk.Frame(root)
frame.pack(expand=True)

button = tk.Button(frame, text='閉じる', command=root.destroy)
button.pack()

if __name__ == "__main__":
    root.mainloop()

実行結果はこちら

tkinterを使って「閉じる」ボタンだけの簡単なウィジェットを表示してます。この記事ではtkinterの説明はしません。

次にインストーラーにbuildする用のpyファイルを下記のように用意します。

setup.py
import sys
from cx_Freeze import setup, Executable

build_exe_options = {
    # 取り込みたいパッケージをこの中に記載します。
    "packages": [
        "tkinter",
    ],
    # 除外したいパッケージをこの中に記載します。
    "excludes": [
        "pandas",
    ],
}

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    # アプリの名前
    name="MyApp",
    version="0.1",
    # アプリの説明
    description="My GUI application!",
    options={
        "build_exe": build_exe_options,
    },
    executables=[
        Executable(
            # 実行ファイル名を記載します。
            script="myApp.py",
            base=base,
        ),
    ],
)

Pandasやnumpyを取り込んでexe化すると数百MBのファイルがbuildされます。
取り込むライブラリによっては膨大なファイルになってしまうので、使用してないライブラリ等は"excludes":[]内に記載して除外するようにしています。

インストーラーを作成する

下記コマンドを実行します。

PowerShell
python setup.py bdist_msi

実行結果のcreating distの後にerrorがなければ問題なくインストーラーがbuildされています。
errorになっても生成されることがあるので、インストーラーの動作確認は必要になります。

OK
...
creating dist
removing 'build\bdist.win-amd64\msi' (and everything under it)
(venv) PS C:\Users\xxxxx\Documents\test>
Error
...
creating dist
Traceback (most recent call last):
  File ...
...
ValueError: FCI error 1
(venv) PS C:\Users\xxxxx\OneDrive\ドキュメント\test>

コマンド実行が完了するとbuildとdistというフォルダが作成されます。

この中にある.msiファイルがインストーラーですのでこのファイルを配布します。

配布方法は様々ありますが、私はGoogle Driveのリンクを共有して配布しています。
配布先のPCの環境にもよりますが、セキュリティの警告が出る場合がありますので、別途確認をお願いします。

アプリを使用する

インストールが完了すると下記のような構成のファイルやフォルダが生成されます。

この.exeファイルをダブルクリックでアプリを実行できます。

おまけ

ここまでで基本的なアプリのインストーラーは作成できますが、公式のリファレンスを読むと様々なオプションも用意されています。
ここではインストーラーに取り込みたいファイルがある場合のsetup.pyの記載方法を紹介します。

先ほど使用していたフォルダにtest.csvファイルとtestsフォルダを作成します。

setup.py内に取り込みたいファイル名やフォルダ名を下記のように追記します。

setup.py
import sys
from cx_Freeze import setup, Executable

build_exe_options = {
    "packages": [
        "tkinter",
    ],
    "excludes": [
        "pandas",
    ],
    # 取り込みたいファイルやフォルダ名を記載します。
    "include_files": [
        "test.csv",
        "tests/"
    ],
}

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name="MyApp",
    version="0.1",
    description="My GUI application!",
    options={
        "build_exe": build_exe_options,
    },
    executables=[
        Executable(
            script="myApp.py",
            base=base,
        ),
    ],
)

"tests/"と記載することでtestsフォルダ内の全てのファイルを取り込むことが出来ます。

最後に

pyファイルをexeファイルに変換できる有名なライブラリとしてpyinstallerがありますが、使用するライブラリが多いと生成されたexeファイルの動作が遅くなることがあったので、私はcx_Freezeを使うようにしています。

この記事では基本的な使用方法を紹介しましたが、人によって実現したい内容が変わってくるかと思いますので、気になる方は公式リファレンスを読んでみることをおすすめします。

Discussion