py2exeでハマったことの解決法

環境は Windows + Python 2.7.2 + virtualenv 1.7

UAC で管理者権限を要求する

# -*- encoding: utf-8 -*-
from distutils.core import setup
import py2exe #python setup.py py2exe するために必要

setup(
    console = [{'script' : 'hoge.py', 'uac_info' : "requireAdministrator",}],
)

実行時発生する ImportError を回避する

via http://stackoverflow.com/questions/1979486/py2exe-win32api-pyc-importerror-dll-load-failed

# -*- encoding: utf-8 -*-
from distutils.core import setup
import py2exe #python setup.py py2exe するために必要

py2exe_options = {
    'dll_excludes': [ "mswsock.dll", "powrprof.dll" ],
}

setup(
    options = {'py2exe': py2exe_options},
)

VC2008 ランタイムの問題を回避する

Python 2.6 からは VC2008 でコンパイルされているため、 VC2008 ランタイムの問題が発生する。特に問題なのは、ほとんどの環境では SP1 までアップデートされるため、バージョンが 9.0.30729.XX になること。Python が要求するのは 9.0.21022.8 であり、このバージョンのランタイムがないと exe が起動できない。基本的に Windows Update すれば問題はなくなるはずだが、OSのクリーンインストール直後などでも動作できるようにしたい。開発マシンの C:\Windows\WinSxS には該当のDLLが存在するはずなので、これを集めてくるようにすれば問題ないはず。

# -*- encoding: utf-8 -*-
from distutils.core import setup
from glob import glob
import os
import py2exe #python setup.py py2exe するために必要

candidates = glob(r"C:\Windows\winsxs\Manifests\x86_microsoft.vc90.crt_*_9.0.21022.8_*.manifest")
if not candidates:
    raise Exception("Could not find VC9 runtime( 9.0.21022.8 ) from 'C:\Windows\winsxs'.")

dirname = os.path.splitext(os.path.basename(candidates[0]))[0]
data_files = [("Microsoft.VC90.CRT", [candidates[0]] + glob(os.path.join(r"C:\Windows\winsxs", dirname, "*.*")))]

setup(
    data_files=data_files,
)

2012/01/14 追記
上記のままだとmanifest名が正しくないため、名前をリネームする必要がある。

from glob import glob
import os
import shutil
build_dir = "/path/to/build_dir"
manifests = glob(os.path.join(build_dir, r"Microsoft.VC90.CRT", "*.manifest"))
shutil.move(manifests[0], os.path.join(build_dir, "Microsoft.VC90.CRT", "Microsoft.VC90.CRT.manifest"))