[pygtk] Notes on creating a self-installing executable using py2exe and Inno Setup.

Cribbs, Jamey Jamey.Cribbs at oakwood.org
Thu May 29 09:29:18 WST 2003


Ok, here are some very rough notes on creating a self-executing 
installer of your pygtk app for Windows.  I'm sure there are better ways 
to do this, but this works for me. 

1.)  Install py2exe and Inno Setup.

2.)  Add os.environ['PATH'] += ";gtk/lib;gtk/bin" to top of your script.

3.)  Create an executable of your app using py2exe.  This is going to 
take a lot of trial and error, because, although the exe will probably 
work on your original machine, when you move it to a "clean" machine, 
you invariably will be missing a module that py2exe did not 
automatically include.  Not to worry!  Py2exe give you various ways to 
manually include missing modules.  It's going to take some tweaking, but 
you will get there.  Here is an example of the command line that I use 
for my app:

python setup.y py2exe --force --excludes gtk, gobject,pango --packages 
pyPgSQL --icon fred6.ico

Here's what my setup.py script looks like:

from distutils.core import setup
import py2exe
import glob

setup(name="fredgui",
   scripts=["fredgui.pyw"],
   data_files=[(".",glob.glob("*.bmp")),(".",glob.glob("*.gif")),
               (".",glob.glob("*.png")),(".",glob.glob("*.jpg")),
               (".",glob.glob("*.ico")),(".",glob.glob("*.xpm")),
               (".",glob.glob("../../jgcmodules/*.py"))],
)

4).  Ok, now that I have a exe for my app, I need to copy some 
directories to the "dist/fredgui" directory that py2exe created to hold 
my app.  I copy everything below c:\program files\common files\GTK\2.0 
to a "gtk" directory under my dist/fredgui directory.  I also copy  all 
of the pygtk files (and included subdirectories), from my python 
disribution, into my dist/fredgui directory.

5.)  Now, we turn to Inno Setup.  Here is a copy of my Inno script:

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

[Setup]
AppName=Fred Administrator - Python
AppVerName=Fred Administrator - Python - 2.0
AppPublisher=NetPro Technologies, LLC
AppPublisherURL=http://www.netpromi.com
AppSupportURL=http://www.netpromi.com
AppUpdatesURL=http://www.netpromi.com
DefaultDirName={pf}\fredpython
DefaultGroupName=Fred Administrator - Python

[Tasks]
Name: "desktopicon"; Description: "Create a &desktop icon"; 
GroupDescription: "Additional icons:"

[Files]
Source: "C:\work\python\fred2\fredgui\dist\fredgui\fredgui.exe"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\woman.ico"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\_socket.pyd"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\_sre.pyd"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\application.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\atk.pyd"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\batch_save.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\configure.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\debug.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\exec.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\exit.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\fred6.gif"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\fred6.ico"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\get_index.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\gobject.pyd"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\grid.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_aboutwin.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_browse.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_busycursor.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_database.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: 
"C:\work\python\fred2\fredgui\dist\fredgui\jgc_editdaterange.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_editrec.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_editwin.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_errorwin.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_mainmenu.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_notebookwin.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\jgc_table.py"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\libpq.pyd"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\list_box.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\mail_image.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\mxDateTime.pyd"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\pango.pyd"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\preview.xpm"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\print.png"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\print.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\pygtk.pyc"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\pygtk.pyo"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\python22.dll"; 
DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\quit.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\run.xpm"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\tools.gif"; DestDir: 
"{app}"; Flags: ignoreversion
Source: "C:\work\python\fred2\fredgui\dist\fredgui\gtk\*.*"; DestDir: 
"{app}\gtk"; Flags: ignoreversion recursesubdirs
Source: "C:\work\python\fred2\fredgui\dist\fredgui\pyPgSQL\*.*"; 
DestDir: "{app}\pyPgSQL"; Flags: ignoreversion recursesubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\Fred Administrator - Python"; Filename: 
"{app}\fredgui.exe"; WorkingDir: "{app}"
Name: "{group}\Uninstall Fred Administrator - Python"; Filename: 
"{uninstallexe}"
Name: "{userdesktop}\Fred Administrator - Python"; Filename: 
"{app}\fredgui.exe"; Tasks: desktopicon; WorkingDir: "{app}"

[Run]
Filename: "{app}\fredgui.exe"; Description: "Launch Fred Administrator - 
Python"; Flags: nowait postinstall skipifsilent

6.)  I compile the script and it creates a setup.exe.  Copy this to a 
"clean" machine and run it.  It should install the app, create desktop 
icon, start menu icons, etc.  Try to run the app.  If it doesn't work, 
chances are that you are missing a module that didn't get included in 
either py2exe or Inno setup.  One cheezy way to debug it is to initially 
create the executable in py2exe as  a console app (using the --console 
flag in py2exe).  This means that, even though the app is a gui, it will 
still open a dos box when it runs on the target machine.  This will 
alllow you to see the error message that gets generated when it bombs 
out on the clean machine.

7).  Don't give up.  It will probably take several tries, but eventually 
you will end up with a working executable on the clean machine!

Note:  The above instructions are an EXTREMELY cheezy way to accomplish 
the task of creating a self-installing pygtk app.  I'm sure that there 
are many more efficient ways of doing this.  Also, my knowledge of 
py2exe and Inno setup is VERY limited, so I'm sure that there are things 
that could be done much better using these tools.

I hope these notes have been helpful (and that I didn't forget any steps!).

Jamey Cribbs

Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.


More information about the pygtk mailing list