11

I have been trying to make a single executable file and I am getting close. Please do not recommend that I use PyInstaller -- I have tried that route, asked on SO here, and have put in tickets. It is close but not quite working. I am now trying py2exe and am also very close. In pyinstaller, I am able to create resource files (which builds the executable with the files included -- I can then access these in the temporary folder).

I want to do the same for py2exe. I have a single executable, but five extra folders (maps, mpl-data, data, pics and tcl). I have seen this question but can't seem to understand it, nor get it to work. In my main py file, I am using PersistentDict(filepath) which is where I need the path to the file.

My question is two parts: 1. How do I get the files (data files below) packaged into the executable. 2. How do I access these files in my code and return their path (as a string) such as /temp/file1.jpg.

Here is my code for my py2exe setup file -- note that I have matplotlib and must include the mpl-data correctly in my executable. Thanks!

from distutils.core import setup 
import py2exe 
import shutil
import glob 
import matplotlib,six

opts = {'py2exe': { "includes" : ["matplotlib.backends",
                                  "matplotlib.backends.backend_qt4agg",
                                  "matplotlib.figure","numpy",
                                  "six",
                                  "mpl_toolkits.basemap", 
                                  "matplotlib.backends.backend_tkagg"], 
                     'excludes': ['_gtkagg', '_tkagg','_agg2','_cairo',
                                  '_cocoaagg', '_fltkagg', '_gtk', '_gtkcairo', 'tcl' ], 
                 'dll_excludes': ['libgdk-win32-2.0-0.dll','w9xpopen.exe', 
                                 'libgobject-2.0-0.dll'],
                    'bundle_files': 1,
                    'dist_dir': "Dist Folder",
                    'compressed': True,
              } 
       }

data_files = [(r'mpl-data', glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\*.*')),
              (r'mpl-data', [r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\matplotlibrc']), 
              (r'mpl-data\images',glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\images\*.*')), 
              (r'mpl-data\fonts',glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\fonts\*.*')),
              (r'mpl-data\data', glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\data\*.*')),
              ('data', ['C:\\Users\\Me\\Documents\\Example_Json_File.json']),
              ('pics', ['C:\\Users\\Me\\Documents\\Example_Icon.ico',
                        'C:\\Users\\Me\\Documents\\Example_Jpg.jpg',
                        ])]


setup(windows=[{"script" : "MyMainScript.py",
                "data_files" : data_files,
                "icon_resources": [(1, 'C:\\Users\\Me\\Documents\\Example_Icon.ico')]}, ],

                version = "1.0", 
                options=opts,
                data_files=data_files,
                zipfile = None,
      ) 
Community
  • 1
  • 1
mcfly
  • 1,151
  • 4
  • 33
  • 55
  • Have you tried [IExpress](https://en.wikipedia.org/wiki/IExpress)? It was originally designed for installing device drivers and IE 6 (shudder), but I've abused it before for exactly your use case. – Lambda Fairy Nov 11 '13 at 04:16
  • I dont think this is what I want. I am using Inno Setup which seems similar to this. When I give the executable (or installer) to another user, I want them to only have an executable -- no files associated with it that they could see/change (thus the files are built into the executable). – mcfly Nov 11 '13 at 04:27
  • So what exactly do you want the executable to do? Do you want it to 1) extract itself into a temporary folder, 2) run your program, 3) when the program finishes, delete the temporary files? That's what IExpress does. – Lambda Fairy Nov 11 '13 at 04:36
  • Okay -- let me take a deeper look into this. Will the user have any way to see the extracted files (this is mainly what I am trying to avoid). – mcfly Nov 11 '13 at 18:36

2 Answers2

4

Guy here explains how to package to one file with py2exe. He's setup doesn't package resources inside the executable either.

When I package my apps, I don't use one executable option

options = {"py2exe": {'bundle_files': 1, 'compressed': True}},

not even bothered to put them in library.zip via

options = {"py2exe": {"skip_archive":0}}

Just have a number of pyc's, data files, dlls etc in one dir. Then create an installer using NSIS or Inno setup. As some of my apps have to run as services, Inno was taking care of that. The biggest plus of that approach, you don't have to deal with "frozen" paths to your files, that are different from your original paths.

Otherwise you might need to alter your code to detect frozen paths, e.g. http://www.py2exe.org/index.cgi/WhereAmI

Community
  • 1
  • 1
Dmitriy
  • 340
  • 2
  • 9
  • This is how I am doing it now. However, this does not give me one executable file -- I must include the folders with it. I do want frozen paths -- this is where I am struggling. I can't seem to get the actual files into the executable and then be able to address their frozen paths. – mcfly Nov 14 '13 at 16:19
0

I've seen a batch to EXE converter (Advanced Batch to EXE Converter) do this, but in an odd way: It would let you put your files in a "bake" directory, and they could be manipulated via the "%MYFILES%\[path]" directory/variable. If you have some wiggle room, check this out. The only problem is it'll add an "intro" (read: glorified Flash animation) to the file, and it'll show FIRST. (I'm against piracy, but I'd be OK with it here... the "intro" is 45 seconds long and obnoxious.)

If that does not bug you, try giving that a shot.