# # Gramps - a GTK+ based genealogy program # # Copyright (C) 2010 Stephen George # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: $ import sys import os import _winreg from ctypes.util import find_library import getopt import string NOT_FOUND_STR ='Not Found' #small selection of DLL's to test testdlls = ['libgdk-win32-2.0-0.dll', 'libglib-2.0-0.dll', 'libgobject-2.0-0.dll', 'libcairo-2.dll', ] explain_exposed = ''' *********************************************************** * It seems that other installations are exposing GTK DLL's * to the operating system as they are in the environment * path variable BEFORE the runtime directory. * You should reorder the path variable to put your GTK * runtime path before these other installations on the path''' explain_safe = ''' *************************************************************** * While there are other installations of GTK DLL's on the path, * it should be safe as they are on the path AFTER the runtime * directory. ''' def RunExeCommand( app, args ): cmd = app + ' ' + args #print "Running: ", cmd stdin, stdout, stderr = os.popen3( cmd ) output = string.strip(stdout.read()) #print output err = stderr.read() if err: print err return output def CheckGtkInReg(): global gtkPathInRegistry, gtkVersionInRegistry, dllPathInRegistry, dllPathShort print '\n==== Checking Registry for GTK =====' try: with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\GTK\\2.0') as key: gtkVersionInRegistry = _winreg.QueryValueEx(key, 'Version')[0] gtkPathInRegistry = _winreg.QueryValueEx(key, 'Path')[0] dllPathInRegistry = _winreg.QueryValueEx(key, 'DllPath')[0] print ' Version :', gtkVersionInRegistry print ' Path :', gtkPathInRegistry print ' DllPath :', dllPathInRegistry except WindowsError, e: print '\n GTK registry key not found in registry' print ''' ******************************************************************** * This might not be an error, but means I don't know the directory to * your preferred GTK installation. * - try passing in your GTK installation path.\n''' print '-' * 60 print usage sys.exit(0) def WorkOutShortDosPath(): global dllPathShort print '\n==== Use win32Api to query short path name for GTK =====' try: import win32api dllPathShort = win32api.GetShortPathName(dllPathInRegistry) print ' DllPath8.3:', dllPathShort except ImportError: print ' **Cant query short path name, Win32Api not installed' print ' install from http://python.net/crew/mhammond/win32/' print ' if you want this function to work' def FindLibsWithCtypes(): # use ctypes to check where windows finds it's DLL's print '\n==== Use ctypes to find dlls ====' other_paths = [] for dll in testdlls: dllpathvalid = False cpath = find_library(dll) if cpath: #print cpath if cpath == os.path.join(dllPathInRegistry, dll) \ or cpath == os.path.join(dllPathShort, dll): dllpathvalid = True if not dllpathvalid: pp = os.path.dirname(cpath) if pp not in other_paths: other_paths.append(pp) else: print " ERROR:... ctypes failed to find %s" % dll if other_paths: for pth in other_paths: print " ERROR: ctypes loaded some gtk dll's from %s" % pth else: print " OK ... ctypes found dll's in %s" % os.path.dirname(cpath) def ScanDependencyFileForErrors(fname): fin = open(fname, 'r') lines = fin.readlines() fin.close() sysroot = os.environ["SystemRoot"] capture = False runtimedlls = {} for line in lines: if line.startswith(" Module"): # work out were paths end pthend_idx = line.find("File Time Stamp") acceptablePaths = [ dllPathShort.lower(), dllPathInRegistry.lower(), os.path.join(sysroot, 'system32').lower() ] if line.startswith('----- ------------'): capture = True if capture and line.startswith('['): filename = line[5:pthend_idx].strip() dirname = os.path.dirname(filename).strip() parts = line[pthend_idx:].split() OK = False if dirname.startswith(os.path.join(sysroot, 'winsxs').lower()) \ or dirname.startswith(os.path.join(sys.prefix, 'lib\site-packages\gtk-2.0').lower()): OK = True for pth in acceptablePaths: if dirname == pth.lower(): OK = True if 'MSVCR90.DLL' in filename: if parts[0] == 'Error': runtimedlls[filename] = "Error dll not found" else: runtimedlls[filename] = parts[16] if OK == False: if parts[0] == 'Error': print " %s \tError dll not found" %( filename) else: print " ERROR: %s \tVersion %s" %( filename, parts[16]) for rtdll in runtimedlls: if runtimedlls[rtdll].startswith("Error"): print '\n ERROR: MS runtime %s not found'%rtdll else: print '\n MS runtime Version %s loaded from' % runtimedlls[rtdll] print " %s" %rtdll print def CheckWithDependencyWalker(): print '\n==== Checking with Dependency Walker ====' print ' Please be patient takes some time' exe = os.path.join(scriptpath, 'depends.exe') fout = os.path.join(scriptpath, 'depres.txt') f2check = [ os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/gtk/_Gtk.pyd' ), os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/gobject/_GObject.pyd' ), os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/pangocairo.pyd' ), ] if os.path.isfile( exe ): for ftest in f2check: if os.path.isfile( ftest ): #delete the output file before running command try: os.remove(fout) except WindowsError, e: pass print ' Testing file %s' % ftest out = RunExeCommand(exe, '/c /f1 /ot "%s" "%s"' % (fout, ftest) ) if os.path.isfile(fout): ScanDependencyFileForErrors(fout) else: print " ERROR: file %d does not exist", ftest else: print ' Cannot check with dependency walker, not installed in local directory' print ' get dependency walker from http://www.dependencywalker.com/' print ' and unzip into this directory for it to work.' def CheckPathForOtherGtkInstalls(): print '\n====Checking environment path for other gtk installations====' ePath = os.environ['path'] dirs = ePath.split(';') gtkpth_idx = 9999 other_paths = [] explain_level = 0 for i, d in enumerate(dirs): #print '==%s==' %d if d == gtkPathInRegistry or d == dllPathInRegistry\ or d == dllPathShort: gtkpth_idx = i continue for fname in testdlls: f = os.path.join(d, fname) if os.path.isfile( f ): #print ' Found Erronous gtk DLL %s' % f if d not in other_paths: other_paths.append(d) if i < gtkpth_idx: # path appears BEFORE runtime path print ' ERROR: %s should not appear before runtime path' % d explain_level = 2 else: print ' FOUND: %s, Probably OK as appears AFTER runtime path' % d if explain_level <= 1: explain_level = 1 if gtkpth_idx == 9999: print '\n ERROR: Runtime directory not on enviroment path' print " ** Runtime needs to be on path to load DLL's from\n" if explain_level == 2: print explain_exposed elif explain_level == 1: print explain_safe if len(other_paths) == 0: print ' No other gtk installatons found\n' # ==== report what python thinks it's using ===== MIN_PYTHON_VER = (2,5,1) UNTESTED_PYTHON_VER = (3,0,0) MIN_GTK_VER = (2,10,11) UNTESTED_GTK_VER = (2,16,7) MIN_PYGTK_VER = (2,10,6) UNTESTED_PYGTK_VER = (2,12,2) MIN_GOBJECT_VER = (2,12,3) UNTESTED_GOBJECT_VER = (2,14,3) MIN_CAIRO_VER = (1,2,6) UNTESTED_CAIRO_VER = (1,4,13) def PrintFailedImport(appl, minVersion, result): print appl, print 'version %d.%d.%d or above.....\t' % minVersion , print result def PrintVersionResult(appl, minVersion, actualVersion, untestedVersion): print appl, print 'version %d.%d.%d or above.....\t' % minVersion , print 'found %d.%d.%d' % actualVersion , if minVersion <= actualVersion < untestedVersion: print '...OK' elif actualVersion >= untestedVersion: print '...UNTESTED VERSION' else: print '...FAILED' def Import_pyGtkIntoPython(): print '\n==== Test import into python ====' #py_str = 'found %d.%d.%d' % sys.version_info[:3] PrintVersionResult(' Python ', MIN_PYTHON_VER, sys.version_info[:3], UNTESTED_PYTHON_VER) # Test the GTK version try: import gtk PrintVersionResult(' GTK+ ', MIN_GTK_VER, Gtk.gtk_version, UNTESTED_GTK_VER ) #test the pyGTK version (which is in the gtk namespace) PrintVersionResult(' pyGTK ', MIN_PYGTK_VER, Gtk.pygtk_version, UNTESTED_PYGTK_VER ) except ImportError: PrintFailedImport(' GTK+ ', MIN_GTK_VER, NOT_FOUND_STR) PrintFailedImport(' pyGTK ', MIN_PYGTK_VER, 'Cannot test, ...GTK+ missing') #test the gobject version try: import gobject PrintVersionResult(' gobject', MIN_GOBJECT_VER, GObject.pygobject_version, UNTESTED_GOBJECT_VER) except ImportError: PrintFailedImport(' gobject', MIN_GOBJECT_VER, NOT_FOUND_STR) #test the cairo version try: import cairo PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER ) except ImportError: PrintFailedImport(' cairo ', MIN_CAIRO_VER, NOT_FOUND_STR) #test for glade print '\n==== See if libglade installed ====' try: import Gtk.glade print ' Glade tesing import of libglade .......\tOK\n' except ImportError, e: print ' Glade importError: %s\n' % e if __name__ == '__main__': usage = '''Check for common problems in GTK/pyGTK installation. Usage: python %s [options] [gtkPath] Arguments: gtkPath Path to your GTK installation directory (not the bin dir) Options: None ''' %(os.path.basename(__file__) ) gtkPath = None gtkPathInRegistry = NOT_FOUND_STR gtkVersionInRegistry = NOT_FOUND_STR dllPathInRegistry = NOT_FOUND_STR dllPathShort = 'NoShortPath' scriptpath = os.path.dirname(sys.argv[0]) try: opts, args = getopt.getopt(sys.argv[1:], "", []) for o, a in opts: if o in ("-h", "--help"): print usage sys.exit(0) if len(args) > 1: raise getopt.GetoptError, '\nERROR: Too many arguments' for arg in args: if os.path.isdir(arg): gtkPath = arg else: raise getopt.GetoptError, '\nERROR: Not a valid GTK path %s' % arg except getopt.GetoptError, msg: print msg print '\n %s' % usage sys.exit(2) import platform winver = platform.win32_ver() if len(winver) == 4: print '''\n==== platform.win32_ver() reports ==== Operating System: %s Version : %s Service Pack : %s OS type : %s''' % winver else: print winver if gtkPath: gtkPathInRegistry = gtkPath dllPathInRegistry = os.path.join(gtkPath, 'bin') print ' Using %s as GTK install path' % gtkPathInRegistry print ' Using %s as GTK dll path' % dllPathInRegistry else: CheckGtkInReg() WorkOutShortDosPath() FindLibsWithCtypes() CheckPathForOtherGtkInstalls() Import_pyGtkIntoPython() CheckWithDependencyWalker()