2014-06-20 10:12:30

Hello,
I have a rather extensive pygame project and I tried using py2exe on it and I am getting a lot of errors. I found
pygame2exe
but I'm still getting errors. Mainly my .ogg files aren't able to be played in the .exe version. They play just fine without the compression, and I changed the line that includes the .ogg dll to always load it, but I'm still getting errors. Does anyone have any ideas?
Here is the basic sketch of my project, it will get larger, but no more complex than this

2014-06-20 11:50:59

A working example is there:
https://github.com/soundmud/soundrts/bl … l/setup.py

Some dll are probably missing. Try to copy at least libogg-0.dll from pygame's folder.
You might need also: SDL.dll zlib1.dll
py2exe gives a list of dll at the end of the execution.
If it doesn't work, copy all the dll from pygame and delete some files to check what is useful.

2014-06-20 22:25:03 (edited by frastlin 2014-06-21 08:21:53)

Do I just paste the dlls into the same folder as the .exe file?

Also, what is:

      console=["server.py"]

I'm also not sure what you mean by the comment on the line:

def data_files_from_tree(source_dir): # the installation directory must have the same name

2014-06-21 12:48:54

Yes, paste the dlls into the same folder as the exe file. That's what my example does with:

      data_files=[("", [r"%s/freesansbold.ttf" % PYGAME_DIR,
                        r"%s/SDL.dll" % PYGAME_DIR,
                        r"%s/SDL_ttf.dll" % PYGAME_DIR,
                        r"%s/libfreetype-6.dll" % PYGAME_DIR,
                        r"%s/libogg-0.dll" % PYGAME_DIR,
                        r"%s/zlib1.dll" % PYGAME_DIR,
                        ] ) ]

server.py is a standalone server in console mode (the executable opens a shell).
You can completely ignore the data_files_from_tree() function because it's not used. I copy the other files from another script.

2014-06-21 18:50:09 (edited by frastlin 2014-06-21 19:05:33)

Oh, so I don't need the sirver.py. I commented that line. I made sure the libogg-0.dll was in there as well as the libvorbis-0.dll and I get this error:

Traceback (most recent call last):
  File "map.py", line 186, in <module>
  File "map.py", line 166, in main
  File "background_sound.pyc", line 13, in background
pygame.error: Couldn't read from 'sounds/start.ogg'
Traceback (most recent call last):
  File "map.py", line 186, in <module>
  File "map.py", line 166, in main
  File "background_sound.pyc", line 13, in background
pygame.error: Couldn't read from 'sounds/start.ogg'

map.py is the name of my main module.
sounds/start.ogg is the name of the first sound file. I'm able to play it when running map.py, so the file is OK for that.
Do you have any ideas of why the .ogg files aren't playing?
*note*
I just changed the .ogg to .wav and I still get the same error as above, but with .wav at the end instead. So something in the sound module is not working.
Also, is there a way to:
1. put all the dlls into the .exe that is distributed, or
2. put the dlls into a file called dependencies or something like that?
Having all these files is kind of ugly IMO.

2014-06-21 20:37:19

Maybe the game isn't finding the sound files at all. Did you copy the "sounds" folder to the folder containing the exe file?

I don't know a way to hide the dlls. I use Inno Setup to build an installer so the user notices only the shortcuts.

2014-06-21 21:53:30 (edited by SoundMUD 2014-06-21 21:58:03)

The following files are working. Run py2exe.bat. Don't forget to copy "sounds" to the dist folder.

setup.py

from distutils.core import setup
import glob
import os
import os.path
import sys

import py2exe


PYGAME_DIR = os.path.join(os.path.split(sys.executable)[0],
                          "Lib\site-packages\pygame")

setup(console=["map.py"],
      data_files=[("", [r"%s/libogg-0.dll" % PYGAME_DIR,
                        ]
                   ),
                  ],
      options = {'py2exe': {
      'bundle_files': 1,
      'excludes': ['tkinter', '_tkinter', 'Tkinter', 'numpy', ], 
      'dll_excludes': ['libiomp5md.dll',],
} },
      )

py2exe.bat

c:\python27\python.exe setup.py -q py2exe
pause

2014-06-22 16:08:46 (edited by frastlin 2014-06-22 21:50:12)

Is the py2exe.bat a separate file with the running of the script?

I'm able to hear sound now thank you! But accessible_output is not grabbing NVDA to read the screen. I pasted the nvdaControllerClient32.dll and the nvdaControllerClient64.dll, but I'm still not hearing anything.

This version of the script zips all the dlls and pyd files into a library.zip file.
I'm a little lost though, I opened the library.zip file and there a ton of pyd and dll files. It looks like all of pygame was pasted in there. Is there any reason then for the data_files to call libogg-0.dll? Also, the folder with all the dlls for screen readers is c:\python27\Lib\site-packages\accessible_output\lib\ should I be having that in the data_files list as well? If so where? I think it would go after the libogg, but I'm not 100% sure what the other items are in that list.

*after some testing*
I get a really odd error that it can't copy c:\Python27\Lib\site-packagesccessible_output\lib\nvdaControllerClient32.dll
I did not have the typing error in the script, so I'm very very lost on what happened for that error to happen.
I also realized that library.zip should have libogg in it, but it doesn't. I would like to know how to add files to the library.zip. Also, SAPI is talking, so accessible_output is in there and the NVDA dll is in there, it is just not working. I'll look at the soundRTS mod and see what it has.
Something very odd, the library.zip with the map.exe file must have some kind of incoding that makes it different because if I unzip it and zip it back up with a new dll in it, it doesn't work. I've never seen that happen before...
Do you know if you are using setup from distutils.core to make the directory or py2exe?

2014-06-23 00:16:48

Just as an alternative suggestion here. I often use a script called Pyinstaller instead of py2exe to build executables as I think it works better. However, if you are going to use Accessible Output and some other non-standard modules you'll have to update your Pyinstaller script to recognize them since unlike Pygame Accessible Output is a non-standard module. However, Pyinstaller is well worth a look.

Sincerely,
Thomas Ward
USA Games Interactive
http://www.usagamesinteractive.com

2014-06-23 01:01:48

I haven't used accessible_output in a py2exe project yet (I'm interested though). I have used ScreenReaderAPI. Anyway, you might try to copy manually nvdaControllerClient32.dll to the "dist" folder.

The result of py2exe and the recent versions of pygame is not as clean as it used to be. I'll probably try Pyinstaller someday.

2014-06-23 01:49:25

Hello,
I was copying the NVDA controller DLL to the dist folder and it was still not working.

Pyinstaller looks better in a way, but I'm sure py2exe is just as simple, I just need to read the manual LOL...
Part of it is that I don't quite understand how a .exe file works. Also, if I put a password over the .zip folder, (encrypt it) how can I make the .exe filere is a module missing from accessible_output and if there is, do I just make the module into a .pyc file and paste it into the folder? How do I zip the folder to work enter that password when it runs the unpack from the .zip folder?

Also, is the .zip folder basically the whole package of pygame, accessible_output, random and all the other packages and modules my program imports?
How does the NVDA dll work with NVDA? why does one need it? Does accessible_output use the DLL, or does NVDA use the dll to go to the accessible_output? I'm not sure how to compress the folder once I paste all the right dlls and pyc files into it.

2014-06-24 01:33:59

I just tried using pyinstaller.
It looks really easy to use, but still I can't get accessible_output to work.
sad

2014-06-24 15:10:44

This might help:
http://www.freelists.org/post/programmi … d-py2exe,1

A function called accessible_output.py2exe_datafiles() would return the list of the necessary datafiles.

2014-06-24 20:34:18 (edited by frastlin 2014-06-24 20:39:42)

That is fantastic! it works!
Now I've got to read about why he put the + accessible_output.py2exe_datafiles() rather than putting it in the list.
Then I need to figure out how to make it work with pyinstaller!
Are there any computers who still need
w9xpopen.exe?
windows 95 and 98 support, that seems a little extreme IMO. I know some people use XP, but do people still use windows 98 or 95?

2014-06-25 03:04:30

Frastlin, I seriously doubt it. I haven't heard about anyone using Windows 9x in years, and as a programmer I don't even consider Windows 9x support until it is specifically requested. In the last ten years or so I have only gotten like two requests for Windows 98 support, and those were from foreign countries where computer hardware and software are extremely expensive. Plus those requests were a long time ago and its possible both of those people have upgraded to something else by now. However, the point being it is pretty safe not to take Windows 9x support too seriously because nobody else does.

Sincerely,
Thomas Ward
USA Games Interactive
http://www.usagamesinteractive.com

2014-06-25 11:43:05

@frastlin: which version of accessible_output are you using? I can't find py2exe_datafiles in:
https://pypi.python.org/pypi/accessible_output/0.5.5
https://pypi.python.org/pypi/accessible_output/0.7.5

2014-06-26 00:47:07

Hello,
Here is the correct link for all his packages
He has accessible_output (for python 2.7) and accessible_output2 for 3.*.

2015-08-07 01:49:03

sorry to uncover this topic again, but i'm having the same issues with accessible output and no speech. i'm using pyinstaller. i do get sapi. but no nvda. i've copied the dll's into the program's folder. and still no nvda speech

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2015-08-07 02:06:56 (edited by frastlin 2015-08-07 02:11:05)

Hello,
To my knowledge accessible_output2 does not work with compiling. I have not updated in a while, so I don't know if it is fixed. But here is my pygame2exe file. Note the very bottom lines for accessible_output specific code:

# The script from:
#http://www.pygame.org/wiki/Pygame2exe?parent=CookBook
#that changes a pygame game to an exe file.

#this will create a dist directary containing the executable and all the data  dirs.
#all libraries will be bundled in executable file.

try:
    from distutils.core import setup
    import py2exe, pygame
    from modulefinder import Module
    import glob, fnmatch
    import os, sys, shutil
    import operator
except ImportError, message:
    raise SystemExit, "Unable to load module: %s" % message

#hack that fixes the pygame mixer and pygame font:

#save the orriginal before we edit it
originalIsSystemDLL = py2exe.build_exe.isSystemDLL

def isSystemDLL(pathname):
    """replaces the py2exe build_exe function."""
    #checks if the freetype and ogg dlls are being included:
    if os.path.basename(pathname).lower() in ("libfreetype-6.dll", "libogg-0.dll", "sdl_ttf.dll"):
        return 0
    #if not one of the above dlls, return the orriginal function we saved above:
    return originalIsSystemDLL(pathname)

#Now we override the py2exe orriginal function with the one we created above:
py2exe.build_exe.isSystemDLL = isSystemDLL

class pygame2exe(py2exe.build_exe.py2exe):
    """not sure when we call this, but it has the including of the dlls for the music and font modules."""

#Here is a hack to make sure pygame's default font is included:
    def copy_extensions(self, extensions):
        #get pygame default font
        pygameDir = os.path.split(pygame.base.__file__)[0]
        pygame_default_font = os.path.join(pygameDir, pygame.font.get_default_font())

        #add font to the list of extensions to be coppied:
        extensions.append(Module("pygame.font", pygame_default_font))
        py2exe.build_exe.py2exe.copy_extensions(self, extensions)

class BuildExe(object):
    """Now we create the class that handles all the data we will need for our dist folder"""

    def __init__(self):
        #the name of our starting module.py:
        self.script = "my_app_main.py"
        
        #name of program
        self.project_name = "My_app"

        #Project URL:
        self.project_url = "about_none"

        #version of program:
        self.project_version = "1.0"

        #License of the program:
        self.license = "my app's license"

        #Author of program:
        self.author_name = "My Name"
        self.author_email = "[email protected]"
        self.copyright = "Copyright (c) 2015 Me Myself and I"

        #description:
        self.project_description = "My app's description"

        #Icon file, will use pygame default:
        self.icon_file = None

        #extra files or dirs copied to game
        self.extra_datas = []

        #extra or excluded python modules:
        self.extra_modules = []
        self.exclude_modules = []

        #dll excludes
        self.exclude_dll = []

        #python packages to be included (in string form)
        self.extra_scripts = []

        #zip file name, None will bundle files in the exe rather than the zip file
        self.zipfile_name = None

        #dist directory:
        self.dist_dir = 'dir'

    def opj(self, *args):

        path = os.path.join(*args)
        return os.path.normpath(path)

    def find_data_files(self, srcDir, *wildcards, **kw):

        #get a list of files under the srcDir matching the wildcards that is returned in a format to be used for install_data
        def walk_helper(arg, dirname, files):
            if '.svn' in dirname:
                return
            names = []
            lst, wildcards = arg
            for wc in wildcards:
                wc_name = self.opj(dirname, wc)
                for f in files:
                    filename = self.opj(dirname, f)

                    if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename):
                        names.append(filename)

            if names:
                lst.append((dirname, names,))

        file_list = []
        recursive = kw.get('recursive', True)
        if recursive:
            os.path.walk(srcDir, walk_helper, (file_list, wildcards))
        else:
            walk_helper((file_list, wildcards), srcDir, [os.path.basename(f) for f in glob.glob(self.opj(srcdir, '*'))])

        return file_list

    def run(self):

        if os.path.isdir(self.dist_dir):
            shutil.rmtree(self.dist_dir)

        #Use the default pygame icon if none given:
        if not self.icon_file:
            path = os.path.split(pygame.__file__)[0]
            self.icon_file = os.path.join(path, 'pygame.ico')

        #list all datafiles to add
#        extra_datas = []
#        for data in self.extra_datas:
#            if os.path.isdir(data):
#                extra_datas.extend(self.find_data_files(data, '*'))
#            else:
#                extra_datas.append(('.', [data]))
        extra_datas = self.extra_datas


        setup(
            cmdclass = {'py2exe': pygame2exe},
            version=self.project_version,
            description=self.project_description,
            name=self.project_name,
            url=self.project_url,
            author=self.author_name,
            author_email=self.author_email,
            license=self.license,
            zipfile=self.zipfile_name,
            data_files=extra_datas,
            dist_dir=self.dist_dir,


            #targets to build:
            windows=[{
                'script': self.script,
                'icon_resources': [(0, self.icon_file)],
                'copyright': self.copyright,
            }],

            options={'py2exe': {
                'optimize': 2,
                'bundle_files': 1,
                'compressed': True,
                'excludes': self.exclude_modules,
                'packages': self.extra_modules,
                'dll_excludes': self.exclude_dll,
                'includes': self.extra_scripts
                }
            })

        #Remove the build folder
        if os.path.isdir('build'):
            shutil.rmtree('build')

if __name__ == '__main__':
    if operator.lt(len(sys.argv), 2):
        sys.argv.append('py2exe')

    #Run our script:
    build_1 = BuildExe()

    import accessible_output
    datas = accessible_output.py2exe_datafiles()
    datas.append('freesansbold.ttf')
    build_1.extra_datas = datas
    build_1.dist_dir = 'My_project_dir/'
    build_1.run()

    raw_input("Press any key to continue > ")

2015-08-07 02:22:25

well, pygame works fine. its the fact i don't have nvda support. i'm assuming accessible output is fine because i'm getting sapi to read, but nothing from nvda. like i said above i have copied the screenreader dll's in the program folder. is ther anything else i need to do?

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2015-08-07 03:09:56

also, when i try to run your script, i get an error on line 193. saying, module accessible_output has no attribute py2exe_datafiles.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2015-08-07 03:23:35

You need the accessible_output from:
http://hg.q-continuum.net/accessible_output/

2015-08-07 05:18:59

ah well this solves a few questions i had. for one i thought that accessible output came with voiceover support and the version i had didn't. this one does. thank you.
but it also raises questions. i have had the hardest time installing dependencies for accessible_output. i've already installed pywin32:which i know is one of the things you need to install. but its says it can't find win32gui. its trying to get it because jaws.py imports it. does anyone know where this is located at. and if i need to move it anywhere, where might that be. sorry. didn't want to turn this into a descussion on accessible_output. but anyway

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2015-08-07 07:02:20

well, disregard my last post i figured out the win32gui error. if you are having issues with that just force an install of c:\python\scripts\pywin32_postinstall.py and it should fix it.
but now i'm getting an error with sapi stuff. sigh.
any way to accessibly copy text out of powershell/cmd with a screen reader? its a really long error and i'm not typing it all out.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2015-08-07 07:16:48

press alt+space, e, s, alt+space, e, y.

pyaudiogame has the dependencies for that version of accessible_output, but here they are:
accessible_output and its requirements