py2exeでPythonのスクリプトを実行ファイル(exe)にする【py2exe】

py2exeを使って、pythonスクリプトをexeファイルにしましょう。
いくつかハマりポイントがあって大変だったのでまとめてみます。

複数のハマリポイントではまった理由を追記しました(2017/03/13)
Python バージョン: 2.7.10
pyexe バージョン: 0.6.9

pythonスクリプトを書く

今回はこんなかんじの、
ファイルを作るだけの簡単なスクリプトをexeにしようと思います。

create_file.py

with open('test.txt', 'w') as f:
    f.write('Hello, world!')

py2exeをインストール

トップページの上のメニューに有るダウンロードページからpy2exeをダウンロード。

ハマりポイント1
f:id:cocodrips:20150603222628p:plain

インストール自体は簡単。
ただ64bitマシンなのに、64bitのほうじゃ動かなくて、32bitの方にしたら動いた。

追記(2017/03/13)
インストールしてたPythonが32bitだったからだった。


ハマりポイント2
pip install py2exeでは、python3向けのpy2exeしかインストールできないので注意。

exeを作るためのsetup.pyを書く

py2exeではexeファイルを作るための設定を書いてあげないといけない。
作ったpythonスクリプトと同じ階層にsetup.pyというファイルを作る。

.
├── create_file.py
└── setup.py


中身はこんな感じで。

from distutils.core import setup
import py2exe

option = {
    'bundle_files':1,
    'compressed': True
}
setup(
    options = {'py2exe': option},
    console=['create_file.py'],
    zipfile = 'create_file.zip', 
    )
option

bundle_files: いくつのファイルするか。1にしておけばいい。
compressed: Trueにするとバイナリサイズが減るらしい

setupの引数

console: 目的のファイル。ここをconsoleではなくてwindowにすると、実行時にコンソールが立ち上がらないらしい。
zipfile = 生成されるzipファイルの名前。指定しないとlibrary.zipになる。

exeファイルをつくつ

setup.pyも書いたことだし、exeファイルをつくろう。
以下を実行する。

python setup.py py2exe

そうすると、dist/というフォルダが出来て、その中のexeファイルができている。

├── build
│   └── bdist.win32
├── create_file.py
├── dist
│   ├── create_file.exe  <- これがメインのexeファイル
│   ├── create_file.zip 
│   └── w9xpopen.exe
└── setup.py

create_file.exeをダブルクリックすると無事test.txtができた。
やったー。
これでPython環境のはいってないWindowsユーザにもPythonツールがばらまけるぞ!

ハマりポイント3
コマンドプロンプトでは実行できるんだけど、py2exeを認識してくれなくてcygwinでは実行できなかった。cygwinで使うにはパスをどこかに追加してあげなきゃいけないのかなーと思うんだけど、もう調べる気力がないのでだれか教えてください。

追記(2017/03/13)
WindowsPythonにpy2exeをインストールしたのだから、cygwinから実行するPythonWindowsPythonにしない限り使えないのは当然という感じ。

CygwinからWindowsPython使うとパス関係等色々問題が起きるので、cmdではWindowsPythonCygwinではCygwinでインストールしたPython使おう。
py2exeはコマンドプロンプトで使おう。


ちなみに、windows歴1ヶ月の私は、exeファイルは何でもはいってるスペシャル実行ファイルだと思って、「できました!」って先輩にexeファイルだけを渡したのだけど、
distディレクトリ以下をまとめて渡さないと動かせないです。残念。
実体は.zipの中に入っているのですね・・・。

さいごに

ハマりポイントは、py2exeの、というよりもWindowsのハマりポイントでしたね・・・・。
Mac歴21年のWindows超初心者にはWindowsいろいろわからなすぎる(´・ω・`)(´・ω・`)

追記(2017/03/13)

__file__を使おうとすると、py2exeのexe化したときに失敗します。
代わりにsys.argv[0]を使うようにしましょう。

root_dir = os.path.dirname(os.path.abspath(__file__))

のように現在のディレクトリを定義するのに使うことが多いかと思いますが、
その場合はこんな感じで解決してます。

root_dir = os.path.dirname(os.path.abspath(sys.argv[0]))

追記(2017/03/13)

ウイルス対策ソフトによっては以下のようにでてexe化に失敗する事がある。

File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 860, in build_executable
add_resource(ensure_unicode(exe_path), script_bytes, u"PYTHONSCRIPT", 1, True)
RuntimeError: EndUpdateResource: アクセスが拒否されました。

(自己責任で)一時的に保護を無効にして実行してみて下さい。