2

for ages now i have been trying to package my python applications up as a stand alone executable. i have been attempting to use py2exe but it has never seemed to work.

lets say we have machine A and machine B, i build the program on machine A and try to run as an executable on machine B. on the first few attempts when trying to run on machine B it would say FATAL ERROR: Cannot load python library but i thought that was down to the py2exe process saying 1 missing module full:

  1 missing Modules
  ------------------
? readline                            imported from cmd, code, pdb
Building 'dist\workinghoursGUI.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\python34\python34.dll to dist
Copy C:\Python34\DLLs\select.pyd to dist\select.pyd
Copy C:\Python34\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\Python34\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\Python34\DLLs\unicodedata.pyd to dist\unicodedata.pyd
Copy C:\Python34\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\Python34\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\Python34\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\Python34\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\Python34\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy C:\Python34\DLLs\_tkinter.pyd to dist\_tkinter.pyd
Copy DLL C:\Python34\MSVCR100.dll to dist\
Copy DLL C:\Python34\DLLs\tk86t.dll to dist\
Copy DLL C:\Python34\DLLs\tcl86t.dll to dist\

then i saw this question Py2Exe "Missing Modules" and found out i needed to install pyreadline so i did, then the py2exe process didnt return any missing modules like so:

Building 'dist\workinghoursGUI.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\python34\python34.dll to dist
Copy C:\Python34\lib\site-packages\win32\_win32sysloader.pyd to dist\_win32sysloader.pyd
Copy C:\Python34\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\Python34\DLLs\select.pyd to dist\select.pyd
Copy C:\Python34\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\Python34\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\Python34\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\Python34\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\Python34\DLLs\_tkinter.pyd to dist\_tkinter.pyd
Copy C:\Python34\DLLs\unicodedata.pyd to dist\unicodedata.pyd
Copy C:\Python34\lib\site-packages\win32\win32api.pyd to dist\win32api.pyd
Copy C:\Python34\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\Python34\lib\site-packages\win32\win32evtlog.pyd to dist\win32evtlog.pyd
Copy C:\Python34\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy DLL C:\Python34\DLLs\tcl86t.dll to dist\
Copy DLL C:\Python34\MSVCR100.dll to dist\
Copy DLL C:\Python34\DLLs\tk86t.dll to dist\
Copy ExtensionDLL C:\Python34\pywintypes34.dll to dist\

but now on machine B when the .exe is run a window with just the output port> is shown while the application runs fine on machine A

this is my setup file:

from distutils.core import setup
import py2exe,sys,os

setup(console=['workinghoursGUI.py'])

and the imports in my program are all in the standard release of python which are:

from tkinter import *
from tkinter import ttk
import tkinter as tk
import tkinter.messagebox as tkm
import datetime,os,time

im probably doing something obviously wrong but i cant work out what, does anyone know how i can resolve this issue or am i just going to have to give up?

the dist folder looks like this:

dist folder

Community
  • 1
  • 1
badNameHere
  • 109
  • 10
  • Building standalone apps with software like py2exe can be an ugly business. It's doable (I've done many, many times) but you end up spending a lot of time tinkering with the distribution folder (like "manually" copying the missing stuff). Both python and py2exe version are important for this question. Also the results of the log file (that appears in dist when you run the software). [continues...] – armatita Feb 22 '17 at 15:47
  • [...continues] My advise is for you to change the paradigm of your standalone distributions. Instead of trying to package everything using py2exe just distribute a portable version of Python (for example [WinPython](http://winpython.github.io/)) with your software with an .exe or batch file launching the application using the portable version. This is how I'm currently distributing my major standalone applications (for example: [GEOMS2](https://sourceforge.net/projects/geoms2/)). – armatita Feb 22 '17 at 15:51
  • where would i find the logfile? – badNameHere Feb 22 '17 at 15:53
  • Inside the `dist` folder after running the software (I'm not sure it appears if nothing was "logged"). Its been quite a few years since I used py2exe so some things might have changes but the log feature should still be there. – armatita Feb 22 '17 at 15:55
  • its just pyd files and dlls – badNameHere Feb 22 '17 at 15:58
  • Well, it [exists](http://www.py2exe.org/index.cgi/StderrLog) for sure. Try changing the file of your GUI application to .pyw instead of .py (this should make obvious to py2exe that you are running a GUI application). And then run py2exe again. – armatita Feb 22 '17 at 16:05
  • Will try this when I am back on my machine – badNameHere Feb 22 '17 at 16:25
  • Hi @armatita i just got access to both machines again and `.pyw` file extension didnt work again i still just get a window with `port>` – badNameHere Feb 27 '17 at 09:22
  • And still no log file? Also where is `port>` written on your software? Do you use any characters outside the standard unicode? I'm assuming both machines are equivalent (Windows?!), so perhaps the software is just having difficulty in reading or writing a specific string with an unknown character (this has happened to me before in py2exe distributions, and is one of the main reasons I stopped using it). – armatita Feb 27 '17 at 09:30
  • i did some more digging and found out i had to modify my setup file, now im just trying to get around an issue machine B is getting because in my code i had `os.path.dirname(os.path.realpath(__file__))` and machine B is getting `__file__` isnt defined – badNameHere Feb 27 '17 at 10:28

1 Answers1

2

i have finally gotten this to work, using this question py2exe - generate single executable file

i found out i had to modify my setup file which now looks like this:

from distutils.core import setup
import py2exe, sys, os

sys.argv.append('py2exe')
#bundle files set to 2 because its a tkinter app
setup(
    options = {'py2exe': {'bundle_files': 2, 'compressed': True}},
    windows = [{'script': "workinghoursGUI.pyw"}],
    zipfile = None,
)

but then because in my code i was using os.path.dirname(os.path.realpath(__file__)) and py2exe doesnt support __file__, i found myself on this question How do I get the path of the current executed file in Python? and used ArtOfWarfare's answer to get the current path, which is:

from inspect import getsourcefile
from os.path import abspath
...
abspath(getsourcefile(lambda:0))
Community
  • 1
  • 1
badNameHere
  • 109
  • 10