Missing dll's when using Py2Exe, PyGtk, and Glade - python

I'm trying to build my first application using Py2Exe and I'm following the instructions listed at http://www.py2exe.org/index.cgi/Py2exeAndPyGTK, with the exception that I'm creating the UI with Glade. (Its just a very minimal gui with a close button and a label.)
When I try to run the resulting exe, I get an error dialog asking me to check the log file which contains the following error message:
Traceback (most recent call last):
File "pygtkpy2exetest.py", line 8, in <module>
File "gtk\glade.pyc", line 12, in <module>
File "gtk\glade.pyc", line 10, in __load
ImportError: DLL load failed: The specified module could not be found.
So I started digging around a bit, the first thing that I noticed is that it looks like py2exe is not able to find glib modules:
The following modules appear to be missing
['gdk', 'unix', 'glib.GError', 'glib.IOChannel', 'glib.IO_ERR', 'glib.IO_FLAG_APPEND', 'glib.IO_FLAG_GET_MASK', 'glib.IO_FLAG_IS_READABLE', 'glib.IO_FLAG_IS_SEEKABLE', 'glib.IO_FLAG_IS_WRITEABLE', 'glib.IO_FLAG_MASK', 'glib.IO_FLAG_NONBLOCK', 'glib.IO_FLAG_SET_MASK', 'glib.IO_HUP', 'glib.IO_IN', 'glib.IO_NVAL', 'glib.IO_OUT', 'glib.IO_PRI', 'glib.IO_STATUS_AGAIN', 'glib.IO_STATUS_EOF', 'glib.IO_STATUS_ERROR', 'glib.IO_STATUS_NORMAL', 'glib.Idle', 'glib.MainContext', 'glib.MainLoop', 'glib.OPTION_ERROR', 'glib.OPTION_ERROR_BAD_VALUE', 'glib.OPTION_ERROR_FAILED', 'glib.OPTION_ERROR_UNKNOWN_OPTION', 'glib.OPTION_FLAG_FILENAME', 'glib.OPTION_FLAG_HIDDEN', 'glib.OPTION_FLAG_IN_MAIN', 'glib.OPTION_FLAG_NOALIAS', 'glib.OPTION_FLAG_NO_ARG', 'glib.OPTION_FLAG_OPTIONAL_ARG', 'glib.OPTION_FLAG_REVERSE', 'glib.OPTION_REMAINING', 'glib.OptionContext', 'glib.OptionGroup', 'glib.PRIORITY_DEFAULT', 'glib.PRIORITY_DEFAULT_IDLE', 'glib.PRIORITY_HIGH', 'glib.PRIORITY_HIGH_IDLE', 'glib.PRIORITY_LOW', 'glib.Pid', 'glib.PollFD', 'glib.SPAWN_CHILD_INHERITS_STDIN', 'glib.SPAWN_DO_NOT_REAP_CHILD', 'glib.SPAWN_FILE_AND_ARGV_ZERO', 'glib.SPAWN_LEAVE_DESCRIPTORS_OPEN', 'glib.SPAWN_SEARCH_PATH', 'glib.SPAWN_STDERR_TO_DEV_NULL', 'glib.SPAWN_STDOUT_TO_DEV_NULL', 'glib.Source', 'glib.Timeout', 'glib.child_watch_add', 'glib.filename_display_basename', 'glib.filename_display_name', 'glib.filename_from_utf8', 'glib.get_application_name', 'glib.get_current_time', 'glib.get_prgname', 'glib.glib_version', 'glib.idle_add', 'glib.io_add_watch', 'glib.main_context_default', 'glib.main_depth', 'glib.markup_escape_text', 'glib.set_application_name', 'glib.set_prgname', 'glib.source_remove', 'glib.spawn_async', 'glib.timeout_add', 'glib.timeout_add_seconds', 'glib.uri_list_extract_uris']
If I try to manually add the glib module to the "includes" option in setyp.py it doesn't have any effect.
Digging further, I opened up the resulting exe with Dependency Walker, it shows me that there are two dll's missing, MPR.DLL and SHLWAPI.DLL, but both of these are in my system32 folder.
If I just create the UI without glade, I have no problems what so ever, but given that I've already created another application with glade, I'd like to stick with glade if possible. Any suggestions on where to go from here? I'm using Python 2.7, Py2Exe 0.6.9, PyGtk 2.22.6 on Windows XP.
Thanks,
Brent

i'm also having the same problem, however after spending few hours in google, i manage to find the solution.
use dependencywalker and profiling ur xxx.exe
u can download from http://www.dependencywalker.com/
find out the error file (for my case, they are MSJAVA.DLL and libxml2-2.dll)
search ur pc directory and copy them into 'dist' folder. u also can download the missing DLL from other website.
run the dependencywalker again, u will see the error reduce or become no more.
xxx.exe is executable now.
I hope above would helps those who are facing such kind of problem.
Neoh !!!share is care!!!

This may not help, but I had the same issue & it turned out to be a gtk installation issue. This caused problems with the gtk._gtk.pyd file which py2exe produced.
The setup.py I used was pretty much the same as that which py2exe suggests on http://www.py2exe.org/index.cgi/Py2exeAndPyGTK

I had the same error once and fix it. when you run the setup.py py2exe your files are created in win32. pyo as glade.pyo, and when you do you believe in win64 .pyc, at least that's what I experience, which ran the py2exe my app in window7-64 and then gave me the error, but when you create the executable on win32 I did, I think the glade.pyo, then gave me the same error, go to my project and do everithing with
gtk.Builder()
` not use more
gtk.glade.XML("file.glade")
and remove the import gtk.glade of my .py files and my setup.py just use
import gtk
and everything worked perfectly.
I hope my experiences will be of your help.

Related

Pyinstaller to package app hidden-import warning/exceptions

So, I've had some trouble setting up my application through Inno setup Compiler, at first I assumed it was a problem within Inno itself but on further inspection I think it is my actual exe. I am able to create a working exe file that runs my program properly but only on my own pc. I am able to create the setup file that also works through Inno setup but it only works on my own pc. I have sent both the actual exe file and the Inno setup file to another computer and downloaded it there and ran it, both meet the same "Fatal Error: failed to run script tk_app.py". Therefore, the problem must be that I have not been able to pavkage the app properly with pyinstaller.
My prgoram has 5 files in total (all in the same folder): main.py, file1.py, file2.py file3.py, tk_app.py
All of them importing each other and using python libraries. I know that pyinstaller supports librarires such as pandas, tkinter and many more without needing the --hidden-impoort= command and that it will pick up all files within the program if there are files that are importing each other.
So I use the file tk_app.py (which contains my tkinter UI and imports main.py which then goes onto import file1.py which import another file so on)
The pyinstaller command line I use to make the exe is as follows:
PS C:\Users\ripta\Desktop\CODING\CSV_Upload> pyinstaller -w --hidden-import=bs4 --hidden-import=fake_useragent --hidden-import=urllib.prase --hidden-import=urllib.request --hidden-import=os --hidden-import=pandas.io.parsers --icon=trademark_icon.ico --onefile tk_app.py
My question is, will pyinstaller tell me when it needs a given --hidden-import='name' when running becuase it doesn not throw up any errors and does produce a spec file, a build folder and a dist folder containing the exe file.
I have noticed that it throws up WARNINGs or Exceptions (also not sure why it mentions django as I do not import or use it at all inthe application) :
59182 INFO: Loading module hook 'hook-django.db.backends.py' from 'c:\\users\\ripta\\appdata\\local\\programs\\python\\python36-32\\lib\\site-packages\\PyInstaller\\hooks'... 61711 WARNING: Hidden import "django.db.backends.__pycache__.base" not found! 61712 INFO: Loading module hook 'hook-django.py' from 'c:\\users\\ripta\\appdata\\local\\programs\\python\\python36-32\\lib\\site-packages\\PyInstaller\\hooks'... Traceback (most recent call last): File "<string>", line 21, in walk_packages File "c:\users\ripta\appdata\local\programs\python\python36-32\lib\site-packages\django\contrib\gis\admin\__init__.py", line 5, in <module>
Or show Hidden-import not found (Of imports I have no idea about):
149329 WARNING: Hidden import "pkg_resources.py2_warn" not found! 149330 WARNING: Hidden import "pkg_resources.markers" not found!
The fact that the script fails to run on any other computer besided my own leads me to think that it must be lacking a dependency that is only found on my computer, therefore I am not using pyinstaller correctly but am not too sure where exactly I am making the mistake.
First I've uninstalled Setuptools and reinstalled it with specific version. Then, I've imported pkg_resources.py2_warn as hidden import :
pip uninstalled setuptools
pip install --upgrade 'setuptools<45.0.0'
pyinstaller --hidden-import='pkg_resources.py2_warn' tk_app.py
It worked for me.

py2exe "No module named 'site'" from Anaconda

I'm trying to use py2exe to build an executable on 64-bit Windows 7 with Anaconda (Python 3.4) for a project of mine that depends on a lot of libraries. Some of the more complex ones include vispy (pyopengl), PyQt4, numba, and scipy. I've been stepping through various errors to try to get a working executable, but have hit a road block with no clear way forward. Currently, the py2exe command completes, but I get the following error when running the exe:
...
from numba import jit
File "C:\Anaconda3\envs\sift_py2exe\lib\site-packages\numba\__init__.py", line
13, in <module>
from .pycc.decorators import export, exportmany
File "C:\Anaconda3\envs\sift_py2exe\lib\site-packages\numba\pycc\__init__.py",
line 12, in <module>
from .cc import CC
File "C:\Anaconda3\envs\sift_py2exe\lib\site-packages\numba\pycc\cc.py", line
4, in <module>
from distutils.command import build_ext
File "C:\Anaconda3\envs\sift_py2exe\lib\distutils\command\build_ext.py", line
17, in <module>
from site import USER_BASE
ImportError: No module named 'site'
I was able to do a small workaround by adding the C:\Anaconda3\envs\sift_py2exe\Lib directory to sys.path in my main script, but I doubt that's going to help me much later. Not to mention I had more scipy DLL issues after that.
Here are the relevant parts of my setup.py:
try:
import py2exe
from llvmlite.binding.ffi import _lib_dir, _lib_name
kwargs["data_files"] = [('.', [os.path.join(_lib_dir, _lib_name), os.path.join(_lib_dir, "MSVCP120.dll"), os.path.join(_lib_dir, "MSVCR120.dll")])]
kwargs["console"] = [{
'script': 'cspov/__main__.py',
'dest_base': "SIFT",
}]
kwargs["options"] = {'py2exe': {"includes": ["vispy.app.backends._pyqt4", "PyQt4.QtNetwork"]}}
except ImportError:
print("'py2exe' and/or 'llvmlite' not available")
I've tried adding the "Lib" directory in setup.py and then including "site", but it doesn't find the module. Any ideas? Thanks.
Side note: I'm using the Microsoft DLLs from llvmlite as a quick workaround because I couldn't get it to work in any of the normal ways.
This isn't the answer I was hoping for, but I was able to get a working executable when I switched to pyinstaller. All of the other SO questions I saw relevant to my problem had similar "solutions".

Py2exe and selenium - IOError: [Errno 2] No such file or directory: '\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'

I wrote a simple application which uses selenium to nagivate through pages and download their source code. Now I would like to make my application Windows-executable.
My setup.py file:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1,
"dll_excludes": ['w9xpopen.exe', 'MSVCP90.dll', 'mswsock.dll', 'powrprof.dll', 'MPR.dll', 'MSVCR100.dll', 'mfc90.dll'],
'compressed': True,"includes":["selenium"],
}
},
windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
zipfile = None
)
My program (main.py) (with setup.py file) is located in C:\Documents and Settings\student\Desktop. Py2exe builds my exe in C:\Documents and Settings\student\Desktop\dist.
I copied both webdriver.xpi and webdriver_prefs.json files to C:\Documents and Settings\student\Desktop\dist\selenium\webdriver\firefox\, but I'm getting the error when trying to launch my application:
Traceback (most recent call last):
File "main.py", line 73, in <module>
File "main.py", line 58, in check_file
File "main.py", line 25, in try_to_log_in
File "selenium\webdriver\firefox\webdriver.pyo", line 47, in __init__
File "selenium\webdriver\firefox\firefox_profile.pyo", line 63, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Documents and Settings\\student\\Desktop\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'
How to solve this?
Actually, it worked with such setup.py file:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
wd_path = 'C:\\Python27\\Lib\\site-packages\\selenium\\webdriver'
required_data_files = [('selenium/webdriver/firefox',
['{}\\firefox\\webdriver.xpi'.format(wd_path), '{}\\firefox\\webdriver_prefs.json'.format(wd_path)])]
setup(
windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
data_files = required_data_files,
options = {
"py2exe":{
"skip_archive": True,
}
}
)
But the problem is I need to build SINGLE executable.
Have you tried to have a look at this answer for the "bundle_files = 1" problems? It helped me solving that specific problem.
TL;DR --Please check out this tool I built: https://github.com/douglasmccormickjr/PyInstaller-Assistance-Tools--PAT
Might I suggest using PyInstaller instead of py2exe or anything else for that matter since PyInstaller does a far better job in terms of bundling a single executable. I'm on Windows about 90% of the time (no complaints here) with my python coding-- PyInstaller is a way better option than py2exe (for me at least -- I've used/test a great deal of Windows compilers in the past with varied success). Maybe other people suffering from compiling issues could benefit from this method as well.
PyInstaller Prerequisites:
Install PyInstaller from: http://www.pyinstaller.org/
After PyInstaller installation-- confirm both "pyi-makespec.exe" and "pyi-build.exe" are in the "C:\Python##\Scripts" directory on your machine
Download my PyInstaller-Assitance-Tools--PAT (it's just 2 batch files and 1 executable with the executable's source python file too -- for the paranoid)...The file are listed above:
Create_Single_Executable_with_NO_CONSOLE.bat
Create_Single_Executable_with_CONSOLE.bat
pyi-fixspec.exe
pyi-fixpec.py (optional -- this is the source file for the executable -- not needed)
Place the exectuable file called "pyi-fixspec.exe" inside the previous "Scripts" folder I mentioned above...this makes compiling much easier in the long run!
let's get it working now...some slight code changes to your python application
I use a standard function that references the location of applications/scripts that my python application needs to utilize to work while being executed/operated. This function operates both when the app is a standalone python script or when it's fully compiled via pyinstaller.
Here's the piece of code I use...
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
and here's my app using it....
source = resource_path("data\my_archive_file.zip")
that means the app/files look something like this in terms of directory structure:
C:\Path\To\Application\myscript_001.py <--- main application/script intended to be compiled
...
C:\Path\To\Application\data\my_archive_file.zip <---|
C:\Path\To\Application\data\images\my_picture.jpg <---| supporting files in the bundled app
C:\Path\To\Application\info\other_stuff.json <---|
...
Please note that the data/files/folders I'm bundling for my app are below the main executable/script that I'll be compiling...the "_MEIPASS" part in the function lets pyinstaller know that it's working as a compiled application...VERY IMPORTANT NOTE: Please use the function "resource_path" since the "pyi-fixspec.exe" application will be looking for that phrase/function while parsing/correcting the python application pathing
Goto the directory containing the 2 batch files mentioned above and type in either:
Option #1
C:\MyComputer\Downloads\PAT> Create_Single_Executable_with_NO_CONSOLE.bat C:\Path\to\the\python\file.py
The output executable file results in a GUI app when double clicked
Option #2
C:\MyComputer\Downloads\PAT> Create_Single_Executable_with_CONSOLE.bat C:\Path\to\the\python\file.py
The output executable file results in a WINDOWS CONSOLE app when double clicked -- expects commandline activity ONLY
Your new single-file-executable is done! Check for it in this location
C:\Original\Directory\ApplicationDistribution64bit\NameOfPythonFile\dist
If you do edit/change the original python file that has just been previously compiled, please delete the folder/contents of **\NameOfPythonFile** prior to next compile kickoff (you'll want to delete the historical/artifact files)
Coffee break -- or if you wany to edit/add ICONS to the executable (and other items too), please look at the generated ".spec" file and PyInstaller documentation for configuration details. You'll just need to kick off this again in the windows console:
pyi-build.exe C:\path\to\the\pythonfile.spec
You can build a single executable, which will run natively, by using Nuitka. It converts the Python code into C++ and then compiles it.
http://nuitka.net/
It does, however, require that you have a compiler installed. The appropriate versions of either Microsoft Visual C++ or GCC. Microsoft released "Microsoft Visual C++ Compiler for Python 2.7", which can be obtained here at https://www.microsoft.com/en-us/download/details.aspx?id=44266.
A nice installer of MinGW GCC for windows can be found at https://github.com/develersrl/gccwinbinaries with detailed instructions, including which MSVCRTXX.dll version to link with for which version of Python.
Things you will gain from this method of executable generation:
Doing this generates machine code, so it will be more difficult, but not impossible, to reverse engineer. Simply using Py2exe or PyInstaller, which are great for their intended use, only packages the byte compiled Python code, which is easily decompiled (http://www.simonroses.com/2013/10/appsec-myths-about-obfuscation-and-reversing-python/), into a zip appended executable.
Your application will also gain a bit of a speed boost. I wrote a blog post about this kind of thing at (I DO NOT receive money from click throughs or ads).
https://jaredfields83.wordpress.com/2015/12/21/squeezing-more-juice-from-python/.
The problem you have is that selenium is trying to open a file in a way that is not directly compatible with py2exe.
As you can see at line 63 here, selenium must open a preferences file that is usually shipped with the package. It uses the __file__ variable to find it, which doesn't play well with py2exe. As you have found, it is possible to work around that by also packaging up the prefs file in your distribution. However, that is now more than one file.
The py2exe wiki then has a recipe to use NSIS that will build a self-extracting executable of your complete distribution.

Help with Tkinter in py2exe

I'm trying to convert a basic tkinter GUI program to an .exe using py2exe. However I've run into an error using the following conversion script.
# C:\Python26\test_hello_con.py py2exe
from distutils.core import setup
import py2exe
setup(windows=[r'C:\Python26\py2exe_test_tk.py'])
C:\Python26\py2exe_test_tk.py is the following code
import Tkinter as tk
root = tk.Tk()
root.title("Test")
label1 = tk.Label(root,text="Hello!",font=('arial', 10, 'bold'), bg='lightblue')
label1.pack(ipadx=100, ipady=100)
root.mainloop()
This is the error I get when I try to run the newly created .exe
Traceback (most recent call last):
File "py2exe_test_tk.py", line 4, in <module>
File "Tkinter.pyc", line 1643, in __init__
_tkinter.TclError: Can't find a usable init.tcl in the following directories:
{C:/Users/My_Name/lib/tcl8.5} {C:/Users/My_Name/lib/tcl8.5} C:/Users/lib/tcl8.5 {C:/Users/My_Name/library} C:/Users/library C:/Users/tcl8.5.8/library C:/tcl8.5.8/library
This probably means that Tcl wasn't installed properly.
I'm pretty sure it's something in my conversion script thats giving me problems. What did I omit? Or does someone have an example of what the conversion script would look like for a tkinter GUI program? Also is it possible to divert the output .exe files to my desktop?
EDIT:
The error report said that I was missing init.tcl from {C:/Users/My_name/lib/tcl8.5}. So i made that directory and put a copy of init.tcl there. Now when I try to run the .exe it states that MSVCR90.dll is missing from my computer and is needed to run my program.
Also this is python 2.6.5 on Windows 7.
Such errors in Unix world are usually due to incorrect PATH settings or/and incorrectly installed third party modules (the GUI ones you're using). Have you seen this post: py2exe fails to generate an executable ?

MemoryLoadError when trying to run py2exe application

I am attempting to bundle up a Python application using py2exe 0.6.9 and Python 2.6.4 on Windows. While the executable runs just fine on the system I used to build it, it fails when I attempt to run it on another system:
C:\Documents and Settings\Administrator\Desktop\dist>.\backend.exe install
Traceback (most recent call last):
File "boot_service.py", line 6, in <module>
File "zipextimporter.pyo", line 82, in load_module
File "win32serviceutil.pyo", line 9, in <module>
File "zipextimporter.pyo", line 98, in load_module
ImportError: MemoryLoadLibrary failed loading win32api.pyd
I have a strong hunch that I'm missing a library, but I'm unsure which—especially since the dependency checker isn't flagging anything as missing on the target system. How should I proceed?
same question as https://stackoverflow.com/questions/1979486/py2exe-win32api-pyc-importerror-dll-load-failed.
look at setup.py, just excludes these dlls which are included in the system.
'dll_excludes': [ "mswsock.dll", "powrprof.dll" ]
it will help you!
You can do the dll and dependency check manually. When you generate the exe i am sure you have noticed that it prints out the dll's that are required/used. Check on the system, where the exe is not working, if the dll's exist and if they are the same version.
One other thing. Are you copying the whole dist folder to the system or just the exe, because you need the whole dist folder and not just the exe.
Are you doing the py2exe conversion on a 64bit/vista?
I've been writing my code on a vista64bit, and the .exe files I create usually do not work on 32bit XP (those are the two machines i have on hand).
The .exe helpfully throws out a text file with the traceback, and it appears that the 64bit windows uses the win32api.dll. I assume this is a .dll used by 64bit windows to replicate 32bit OS behaviour, so I simply take the same script and do the conversion on the 32bit XP. Hope that helps.
Just for anyone who will come to here in the future. If you are using any kind of win32 library and u stuck with this type of errors you can do the following steps:
The problem issue is that there is a conflict between win32 functions dll files and the py2exe automatically dll files. So to solve this conflict you have to know your functions required dll files, then exclude these files from the setup options
Example:
According to the following code:
import win32crypt
win32crypt.CryptUnprotectData(...)
I used the CryptUnprotectData function so I searched for the CryptUnprotectData required dll and I found the following info enter link description here , As u can see,
"Crypt32.dll" is required.
so I edit my setup.py to be look like that
includes = ["win32crypt"]
dll_excludes=["Crypt32.dll"]
setup(
options = {'py2exe': {'bundle_files': 1, 'compressed': True,'dll_excludes': dll_excludes,'includes': includes}})
and it worked perfectly.

Categories