How can I use py2exe with arcpy?
Question: I'm trying to convert a python script to a stand-alone executable using
py2exe. The script is built mostly using arcpy, with a Tkinter GUI.

The setup.py script is as follows:

    
    
    from distutils.core import setup
    import py2exe
    
    script = r"pathtoscript.py"
    
    options = {'py2exe':{
        "includes": ['arcpy', 'arcgisscripting'],
        "packages": ['arcpy', 'arcgisscripting'],
        "dll_excludes": ["mswsock.dll", "powrprof.dll"]
        }}
    
    setup(windows=[script], options=options)
    

When run, setup.py creates the .exe as expected, but when I try to run the
executable, I get the following error:

    
    
    Traceback (most recent call last):
      File "autolim.py", line 7, in <module>
      File "arcpy\__init__.pyc", line 21, in <module>
      File "arcpy\geoprocessing\__init__.pyc", line 14, in <module>
      File "arcpy\geoprocessing\_base.pyc", line 14, in <module>
      File "arcgisscripting.pyc", line 12, in <module>
      File "arcgisscripting.pyc", line 10, in __load
    ImportError: DLL load failed: The specified module could not be found.
    

I use python 2.7 and arcgis 10.1 - feel free to ask if I've forgotten any
useful information.

Can anyone tell me what I need to do to get the executable working properly?

Many thanks!


Answer: I had the same problem...

Since your users will have python/arcpy installed on their machines have your
arcpy scripts in a data_files directory.

    
    
    setup(windows=[script], data_files=[('scripts', glob(r'/path/to/scripts/*.py')], options=options)
    

Then call them using
[subprocess.Popen](https://docs.python.org/2/library/subprocess.html#subprocess.Popen)

    
    
    import subprocess
    subprocess.Popen(r'python "%s\scripts\autolim.py"' % self.basedir)
    

Popen is non-blocking so it won't freeze your GUI while the arcpy script runs.

If you want to print any print statements in your arcpy script change to

    
    
    p = subprocess.Popen(r'python "%s\scripts\autolim.py"' % self.basedir, stdout=subprocess.PIPE)
    
    while True:
        line = p.stdout.readline()
        if not line:
            break
        sys.stdout.write(line)
        sys.stdout.flush()
    

