py2exe is a simple way to convert Python scripts into Windows .exe applications. It is an utility based in Distutils that allows you to run applications written in Python on a Windows computer without requiring the user to install Python. It is an excellent option when you need to distribute a program to the end user as a standalone application. py2exe currently only works in Python 2.x.

First you need to download and install py2exe from the official sourceforge site

Now, in order to be able to create the executable we need to create a file called setup.py in the same folder where the script you want to be executable is located:

In the code above, we are going to create an executable for myscript.py. The setup function receives a parameter console=['myscript.py'] telling py2exe that we have a console application called myscript.py.

Then in order to create the executable just run python setup.py py2exe from the Windows command prompt (cmd). You will see a lot of output and then two folders will be created: dist and build. The build folder is used by py2exe as a temporary folder to create the files needed for the executable. The dist folder stores the executable and all of the files needed in order to run that executable. It is safe to delete the build folder. Note: Running python setup.py py2exe assumes that you have Python in your path environment variable. If that is not the case just use C:\Python27\python.exe setup.py py2exe.

Now test if your executable works:

GUI Applications

Now it is time to create a GUI application. In this example we will be using Tkinter:

Then create setup.py, we can use the following code:

The setup function now is receiving a parameter windows=['tkexample.py'] telling py2exe that this is a GUI application. Again create the executable running python setup.py py2exe in the Windows command prompt. To run the application just navigate to the dist folder in the Windows Explorer and double-click tkexample.exe.

Using External Modules

The previous examples were importing modules from the Python Standard Library. py2exe includes the Standard Library Modules by default. However if we installed a third party library, py2exe is likely not to include it. In most of the cases we need to explicitly include it. An example of this is an application using the ReportLab library to make PDF files:

In order to include the ReportLab module, we create a setup.py file, passing a options dictionary to the setup function:

The final step to be able to run the executable on other computers, is that the computer running the executable needs to have the Microsoft Visual C++ 2008 Redistributable package installed. A good guide explaining how to do this can be found here. Then just copy the dist folder to the other computer and execute the .exe file.

Finally please take into account the following recommendations:

  • The executable created most of the time is forward compatible: If you create the executable in Windows XP, it will run in Vista and 7. However it is not backwards-compatible: if you create the executable in Windows 7 it is not going to run on Windows XP.
  • If you have imported third party libraries, make sure to test all of the applications functionality before you ship the software, because sometimes the executable is created, but some libraries are missing. In that case you will get a runtime error when you try to access a functionality that uses the external library.
  • py2exe hasn't been updated since 2008, so it is not going to work with Python 3.

If you need more information about py2exe, visit the official site.

  • Absinthia Stacy

    does it work with python 3?

    • http://jacksonc.com Jackson Cooper

      Unfortunately not.

      I’d say your options are:

      1. cx_Freeze, which does support Python 3.x on any platform Python supports.
      2. Run your code through the 3to2 tool, which will convert the code to Python 2.x. Then you can use py2exe. However it’s not perfect, so YMMV.

      Good luck!

  • COBRACHOPPERGIRL

    Having to use a setup.py program is really gross and evil… if this were written properly, you should be able to compile your program.py directly, with py2exe program.py, which would produce program.exe. You pass the compiler your source file, and it produces a binary file. How can you screw that up?

    Well, the py2exe developer found a way to obfusicate things… unnecessarily. Any directives that are in setup.py should be able to be put in your source file header, and be done with.

  • Michelle

    Python is a very good program to learn, but at the end it is useless, because it does not have a good way to make execute files. The py2exe works, if you had your script programmed with 2.x, but if you had installed 3.x, as it also says above, it does not work. So I tried out the cx_Freeze. Total garbage this program. When we had the course last semester, I was wondering, why my friend wasn’t interested in it. He had heard right from the start, that it is a program not very useful for sharing – and at the end, that’s what it is all about. I am on the verge of forgetting about Python too and l am looking for another language, which works from start to finish.

    • http://jacksonc.com Jackson Cooper

      Looks like Py2exe now supports Python 3.x Try it out here: https://pypi.python.org/pypi/py2exe/. I’d be interested to see if it works well. Too bad PyInstaller doesn’t yet :-(.

      • Michelle

        Thanks for giving me this tip. If there is the slightest chance that there is a good compiler program for Python 3.x I will stick with Python.
        cxfreeze hello.py –target-dir dist
        –version –version -O

        What exactly do these writing conventions mean? It is a long time that I had DOS in highschool. The ones with one dash (-O) are switches and are typed probably in as is, but the ones with 2 dashes like –target, I am confused about.
        What exactly does cxfreeze hello.py (the file name) –target (?) -dir (? dist mean?
        I know Visual Basic, but these writing conventions were never used in the tutorials.
        Thank you in advance.
        Michelle

        • http://jacksonc.com Jackson Cooper

          Since Python has command line argument handling baked in with the argparse module, it uses the Unix tradition of command line argument handling. Most Unix programs provide 2 command line switches per configuration option, one is the long form and easy to read, the other a shortcut that’s usually 1 character. For example with the rsync program, -z and --compress are just 2 different ways to turn on compression. When you’re in the interactive shell (console / terminal), it’s quicker just to type -z instead of --compress every time. But if you’re writing a script, you’d want to use the expanded versions to make it easier to read.

          I just tried installing the precompiled (exe download) version of cx_Freeze on Windows and I got the same registry error, looks like it could be a bug in the installer? But installing it with the C:Python34Scriptspip install cx_Freeze command worked fine. To run the cxfreeze script you can type C:Python34python C:Python34Scriptscxfreeze --help (or -h as the short form). This will print a help / usage message showing all command line options. Note 1) This assumes your installation of Python is in the “C:Python34″ folder. 2) You can edit your “%PATH%” variable to add the “C:Python34″ folder, so you can just type python on the command line instead of C:Python34python every time (checkout this to do that, but not essential).

          Also if you also want to try out Py2exe but are facing issues, I’d recommend emailing the py2exe users mailing list (http://lists.sourceforge.net/lists/listinfo/py2exe-users) and ask. It’s quite active, and they’re very helpful.

          I hope that helps, let me know how you go!

        • http://jacksonc.com Jackson Cooper

          cxfreeze --target-name="MyHelloProgram.exe" --target-dir="dist" hello.py means convert the Python file hello.py into a Windows executable called “MyHelloProgram.exe” and place it in the directory “dist”. You can use relative and absolute pathnames, “.” for the current directory and “..” for the parent directory. You can also set the icon of the exe file with the --icon="program-icon.ico" option, assuming there’s the icon file “program-icon.ico” file present.

          • Michelle

            Let’s say my Hello.py script is in the D:Exercises folder. Would I have to be in the D:Exercises folder and type: C:Python33cxfreeze –target-name=”HelloProgram.exe” ???
            The dashes – what do they signify? Do they refer to a directory?

            Or I would copy my Hello.py script into the Python33 directory, to make it simpler. So, would I have to type on the C:python33 cmd line: cxfreeze –target-name=”HelloProgram.exe” ???
            The dashes in front of target (–target) and dir (-dir) confuse me. Just as someone also suggested to type in –help.

          • http://jacksonc.com Jackson Cooper

            Just run cxfreeze --help to see the documentation on all options. No, just add C:Python33 and C:Python33Scripts to %PATH%, referencing the full path every time can get annoying.

            Alternatively, you may want to checkout gui2exe.

          • Michelle

            gui2exe does not exist – it tells me, when I click it.

          • http://jacksonc.com Jackson Cooper

            You can checkout the help message here, hopefully that makes more sense. AFAIK there is no –target or –dir switch.

            --target-name name of the exe file you want to make. eg. --target-name="HelloWorld.exe"
            --target-dir path to the directory the exe file should go. eg. --target-dir="dist". If you are in the directory D:Exercises then this would place the exe in D:Exercisesdist

            Not sure about Python 3.3, but in Python 3.4 cxfreeze is installed in C:Python34Scriptscxfreeze. Can you see the file C:Python33Scriptscxfreeze? Or is it at C:Python33cxfreeze? I also found you have to run cxfreeze from Python, since it’s a Python script.

            Try these 2 commands:

            cd D:Exercises
            python C:Python33Scriptscxfreeze --target-name=Hello.exe --target-dir=dist Hello.py

            Explanation:
            1. Move into the D:Exercises directory.
            2. C:Python33Scriptscxfreeze with Python, telling cxfreeze to convert the file “Hello.py” (in “D:Exercises”) to “Hello.exe” in the directory “dist”. So Hello.py => distHello.exe. Assuming you are in the D:Exercises directory, this would convert D:ExercisesHello.py => D:ExercisesdistHello.exe.

            You don’t have to change directory, you can also use absolute paths:

            python C:Python33Scriptscxfreeze --target-name=Hello.exe --target-dir="D:Exercisesdist" "D:ExercisesHello.py"

          • Michelle

            Thanks for your help. I will try these commands. Will I have to make the dist directory, or will it be created automaticly in the target directory? I will try it both ways. If that doesn’t do it, then I will stay with my py2exe and the 2.x version (2.7).
            The cxfreeze is located in the Scripts directory in Python3.3. I checked out all the directories and found it there. Then when I typed the –help. It worked.
            I just can’t understand why Python brings out versions, when they know they have not a good compiler available for these versions. For someone to program something, it is quite clear, that one wants to share the programs one has created. Even C++ has a build-in compiler. Though Python wouldn’t build-in the compilors, but there should be at least a compiler available which is as good as py2exe. I was wondering, why no one, except 3, I am included in those 3, continued with Python after the semester in Highschool, but they knew, that it wasn’t what they were looking for.

          • Michelle

            I used a cxfreeze setup script and it actually worked and made an execute file which was in the build directory, which also was created by the execute process. However, when I double-clicked the executed file it gave me the following message:
            Cannot import traceback module
            Exception: No module named ‘re’
            Original Exception: No module named ‘re’
            Are you making execute files with python34 and cxfreeze? Maybe I download Python34 then.

          • http://jacksonc.com Jackson Cooper

            Cool! Try adding ‘re’ to the includes variable. eg. includes = ["re"]

            I don’t use cxfreeze myself (or Windows for that matter), I just tried it on Python 3.4.

          • Michelle

            Thanks, if that doesnt work, I will probably stick with the py2exe.
            I find my Python 2.7 version better anyway. I don’t think, I will ever code a rocket science program, just simple games and some useful programs which can be incorporated into my accounting work.
            I have done that with Visual Basic, but I used it only in Excel. It makes the spreadsheets looking very professional. I like Python better and want to use it for stand-alone projects in accounting.
            You think, Python 2.7 will do the job?

  • Michelle

    I downloaded the new py2exe, which is supposed to work on all Python versions, even the 3.x, but it doesn”t even install. It tells me Python is not in your registry. One is better off figuring out cx_Freeze or just stay with the old py2exe, which at least works on the Python 2.x versions – or migrate to a totally different program, which comes with a compiler, like C++.

    • http://jacksonc.com Jackson Cooper

      Hmm, okay. It might be worth the while to delete Python and py2exe, and re-install them fresh. Also note that you need to set %PATH% to be able to run Python directly (https://stackoverflow.com/questions/3701646/how-to-add-to-the-pythonpath-in-windows-7). Otherwise you’ll have to type C:Python34python to run it.

      If you can use Python 2.7 (which is closer to Python 3.x) only, I’ve had good experience with PyInstaller. If you wanted to be an evil genius you could run your code through 3to2 (converting Python 3 code to 2 syntax), then run it lol. Would be interesting.