In this article, I am going to go over the steps needed to package up my program, wxPyMail, so I can distribute it to other Windows users. I will be using Andrea Gavana’s excellent GUI2Exe utility for creating an executable and I’ll use Inno Setup to create an installer. I’ve been told that Andrea is working on a new version of his application, so when it comes out I’ll re-work this article for that version and post it too.
Setting GUI2Exe Up
The process for creating the executable with GUI2Exe is very straightforward. GUI2Exe is actually a GUI front end to py2exe. I highly recommend GUI2Exe for all your executable creating because it is much easier to use. However, if you love the command line than you can use py2exe all by itself. They even include examples for wxPython applications in the Samples directory. Anyway, after downloading GUI2Exe, install it and load the program. You should see something like this now:
Now go to File –> New Project and give your project a name. I’m going to call mine wxPyMail. I’m going to add a fake Company Name, Copyright and give it a Program Name. Be sure to also browse for your main Python script. For this project, it’s wxPyMail.py. According to Andrea’s website, you should set Optimize to 2, Compressed to 2 and Bundled Files to 1. This seems to work most of the time, but I’ve had some screwy errors that seem to stem from setting the last one to “1”. In fact, according to one of my contacts on the py2exe mailing list, the “bundle” option should be set to 3 to minimize errors. The nice thing about setting bundle to “1” is that you end up with just one file, but since I’m going to roll it up with Inno I’m going to go with option “3” to make sure my program works well.
Also note that I’ve included the XP Manifest. This makes your application look “native” on Windows, so your program should match the theme that is currently in effect.
Just to make sure you’re following along, check out the screenshots below:
Once you have everything the way you want it, click the Compile button in the lower right-hand corner. This will create all the files you want to distribute in the dist folder unless you have changed the name by checking the dist checkbox and editing the subsequent textbox. When it’s done compiling, GUI2Exe will ask you if you want to test your executable. Go ahead and hit Yes. I got an error the first time I did this and when I looked at the log, it said it couldn’t find the smtplib module. To fix this particular error, we’ll need to include it.
To include this module, click inside the box labeled Includes and press CTRL+A. You should see an icon appear and the words Edit Me. Just click on those words and type in smtplib. Now try compiling it. I got another screwy error:
Traceback (most recent call last): File "wxPyMail.py", line 20, in import smtplib File "smtplib.pyo", line 46, in ImportError: No module named email.Utils
It looks like I need the email module. Well, if you include the email module then you’ll need to remove it from the Excludes list. However, after doing all that, you’ll still get an error about not being able to import “multipart”. This took me a minute to figure out, but it seems that the email module is actually a package. Thus I add the email package to the Packages listctrl instead. Remove the email module from the Excludes list as before and ALSO remove the smtplib module from the Includes listctrl because it really wasn’t the problem to begin with. To remove items from these controls, you’ll need to right-click the item and choose “Delete Selected”. Now your screen should look something like this:
Note that this is a lot of trial and error. Eventually, you can pretty much guess which modules will be included and which won’t be. It seems that small modules like wmi.py or BeautifulSoup will be grabbed by py2exe, but stuff like the lxml package won’t be. This process does get easier with practice, so don’t give up! Besides, there’s the py2exe group and Andrea which are both good resources if you have questions.
Let’s Make an Installer!
Now that we have an executable and a bunch of dependencies, how do we make an installer? There are various utilities out there, but I’m going to use Inno Setup. After you’ve downloaded that and installed it, run the program. Choose the option labeled “Create a new script file using the Script Wizard”. Click Next and you should see something like this:
Fill this out however you like and click Next. This screen allows you to choose where you want the application to be installed by default. It defaults to Program Files which is fine. Click Next. Now you should see the following screen:
Browse to the executable you created to add it. Then click the Add file(s)… button to add the rest. You can actually select all of the files except for the exe and hit OK. Then click Next. Make sure the Start Menu folder has the right name (in this case, wxPyMail) and continue. You can ignore the next two screens or experiment with them if you like. I’m not using a license or putting information files in to display to the user though. The last screen before finishing allows you to choose a directory to output to. I just left that empty since it defaults to where the executable is located, which is fine with this example. Click Next and Finish.
Now you’ll have a full-fledged *.iss file. Read Inno’s Documentation to figure out what all you can do as that stuff is beyond the scope of this article. Instead, just click the Build menu and choose Compile. If you don’t receive any error messages, then you have successfully created an installer! Congratulations!
One note of caution is in order, however. There seems to be some question on whether or not you can legally distribute the MSVCR71.dll file. Some say that the distribution of this dll requires a license of Visual Studio 2003 and others say the python.org team has licensed VS2003 (i.e. VS7) in such a way that Python becomes “licensee software” and you become a “distributor”. You can read all the gory details on this blog where Python luminaries such as Phillip Eby (of easy_install fame and the major maintainer thereof) and Fredrik Lundh weigh in.
I hope this has helped you on your way to becoming a great Python application developer. As always, feel free to drop me an email at mike (at) pythonlibrary (dot) org if you have any questions or suggestions for improvement.