web-dev-qa-db-ja.com

--onefileとしてのPyInstaller 2.0バンドルファイル

PyInstaller 2.0を使用して、pyスクリプトを.exeとしてバンドルしようとしています。スクリプトをバンドルすることはできますが、私のスクリプトでは、exeにバンドルする必要があるファイルを開く必要があります(移植可能にするため)。これを行うのに問題があります。

私の.pyには、

filename = 'C:\path\to\my\file\doc.docx'
data = open(filename,'rb')

私はPyInstaller 2.0を使用していますが、これは私のコンピューターで正常に動作しますが、exeを別のコンピューターに転送すると動作しません。PyInstaller2.0はかなり新しいため、ドキュメントがほとんどなく、発行元のドキュメントはかなり「欠けている」。

問題に関する発行者の情報は次のとおりです(最初はConfigure.pyを使用するように書かれているため、ドキュメントは最新ではないと思います。他のドキュメントでは、2.0ではConfigure.pyは不要になったと言っています)。

--onefileディストリビューションでは、データファイルは実行可能ファイル内にバンドルされ、実行時にCコードによって作業ディレクトリに抽出されます(ディレクトリツリーを再構築することもできます)。作業ディレクトリはos.environ ['_ MEIPASS2']が最適です。したがって、これらのファイルには次の方法でアクセスできます。

os.path.join(os.environ["_MEIPASS2"], relativename))

それは、初心者プログラマーである私には実際には意味がありません。

出版社とは別の文書によると..

--onefileディストリビューションでは、データファイルは実行可能ファイル内にバンドルされ、実行時にCコードによって作業ディレクトリに抽出されます(ディレクトリツリーを再構築することもできます)。作業ディレクトリはsys._MEIPASSが最適です。したがって、これらのファイルには次の方法でアクセスできます。

os.path.join(sys._MEIPASS, relativename))

私はos.environ ["_ MEIPASS2"]をかなり試しましたが、pythonがos.environment ["_ MEIPASS2"]を理解していないようです。これを元に戻しました:

>>> print os.environ["_MEIPASS2"]

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    print os.environ["_MEIPASS2"]
  File "C:\Python27\lib\os.py", line 423, in __getitem__
    return self.data[key.upper()]
KeyError: '_MEIPASS2'

私もsys._MEIPASSで実験しました。そうです、pythonは、 'module'に属性 '_MEIPASS'がないと応答します。

この時点で、頭が爆発しそうな気がします。PyInstallerの作者の仕事に感謝しますが、そのドキュメントは今まで見た中で最悪です!ファイルをexeにバンドルするのを手伝ってくれる人が必要です。すべての.specが以前のバージョンのPyInstallerと混同されているので、私はPyInstaller 2.0+を本当に使用したいと思います。

ところで、私はpython 2.7.3でWin8 64ビットを使用しています

助けてください!

19
user1914730

ああ、神様!このPyInstallerは本当に私を少し混乱させました。私の以前の投稿が少し「保証」のように聞こえる場合は、それについて申し訳ありません。

これを.pyスクリプトに含めます。

filename = 'myfilesname.type'
if hasattr(sys, '_MEIPASS'):
    # PyInstaller >= 1.6
    chdir(sys._MEIPASS)
    filename = join(sys._MEIPASS, filename)
Elif '_MEIPASS2' in environ:
    # PyInstaller < 1.6 (tested on 1.5 only)
    chdir(environ['_MEIPASS2'])
    filename = join(environ['_MEIPASS2'], filename)
else:
    chdir(dirname(sys.argv[0]))
    filename = join(dirname(sys.argv[0]), filename)

私の名前を覚えていないオンラインの誰かにクレジットを与えてください。

次に、PyInstaller2.0を使用している場合、cmdでpyinstaller-2.0ディレクトリから、次のように実行できます。

pyinstaller.py --onefile myscriptsname.py

これにより、pyinstaller-2.0ディレクトリにmyscriptsname.specファイルが作成されます。また、exeが作成されますが、機能しません。後で更新されます。次に、その.specを編集し、次のa.datas行を追加します(データではなくデータを覚えてください)。参照用に.specファイルに少し余分なものを含めました。

a = Analysis(['ServerTimeTest_nograph.py'],
             pathex=['c:\\Python27\\pyinstaller-2.0'],
             hiddenimports=[],
             hookspath=None)
a.datas += [('myfilesname.type','C:\\path\\to\\my\\file\\myfilesname.type','DATA')]
pyz = PYZ(a.pure)

ここで、cmdに戻って実行します。

pyinstaller.py --onefile myscriptsname.spec

これにより、/ distディレクトリの.exeが更新されます。

より良い方法、またはよりきれいな方法があるかもしれませんが、これは私にとってうまくいきました!

27
user1914730