def __import_pywin32_system_module__(modname, globs): # This has been through a number of iterations. The problem: how to # locate pywintypesXX.dll when it may be in a number of places, and how # to avoid ever loading it twice. This problem is compounded by the # fact that the "right" way to do this requires win32api, but this # itself requires pywintypesXX. # And the killer problem is that someone may have done 'import win32api' # before this code is called. In that case Windows will have already # loaded pywintypesXX as part of loading win32api - but by the time # we get here, we may locate a different one. This appears to work, but # then starts raising bizarre TypeErrors complaining that something # is not a pywintypes type when it clearly is! # So in what we hope is the last major iteration of this, we now # rely on a _win32sysloader module, implemented in C but not relying # on pywintypesXX.dll. It then can check if the DLL we are looking for # lib is already loaded. import imp, sys, os if not sys.platform.startswith("win32"): # These extensions can be built on Linux via the 'mainwin' toolkit. # Look for a native 'lib{modname}.so' # NOTE: The _win32sysloader module will probably build in this # environment, so it may be better to use that here too. for ext, mode, ext_type in imp.get_suffixes(): if ext_type == imp.C_EXTENSION: for path in sys.path: look = os.path.join(path, "lib" + modname + ext) if os.path.isfile(look): mod = imp.load_module(modname, None, look, (ext, mode, ext_type)) # and fill our namespace with it. globs.update(mod.__dict__) return raise ImportError, "No dynamic module " + modname # See if this is a debug build. for suffix_item in imp.get_suffixes(): if suffix_item[0] == '_d.pyd': suffix = '_d' break else: suffix = "" filename = "%s%d%d%s.dll" % \ (modname, sys.version_info[0], sys.version_info[1], suffix) if hasattr(sys, "frozen"): # If we are running from a frozen program (py2exe, McMillan, freeze) # then we try and load the DLL from our sys.path # XXX - This path may also benefit from _win32sysloader? However, # MarkH has never seen the DLL load problem with py2exe programs... for look in sys.path: # If the sys.path entry is a (presumably) .zip file, use the # directory if os.path.isfile(look): look = os.path.dirname(look) found = os.path.join(look, filename) if os.path.isfile(found): break else: raise ImportError, \ "Module '%s' isn't in frozen sys.path %s" % (modname, sys.path) else: # First see if it already in our process - if so, we must use that. import _win32sysloader found = _win32sysloader.GetModuleFilename(filename) if found is None: # We ask Windows to load it next. This is in an attempt to # get the exact same module loaded should pywintypes be imported # first (which is how we are here) or if, eg, win32api was imported # first thereby implicitly loading the DLL. # Sadly though, it doesn't quite work - if pywintypesxx.dll # is in system32 *and* the executable's directory, on XP SP2, an # import of win32api will cause Windows to load pywintypes # from system32, where LoadLibrary for that name will # load the one in the exe's dir. # That shouldn't really matter though, so long as we only ever # get one loaded. found = _win32sysloader.LoadModule(filename) if found is None: # Windows can't find it - which although isn't relevent here, # means that we *must* be the first win32 import, as an attempt # to import win32api etc would fail when Windows attempts to # locate the DLL. # This is most likely to happen for "non-admin" installs, where # we can't put the files anywhere else on the global path. # If there is a version in our Python directory, use that if os.path.isfile(os.path.join(sys.prefix, filename)): found = os.path.join(sys.prefix, filename) if found is None: # Not in the Python directory? Maybe we were installed via # easy_install... if os.path.isfile(os.path.join(os.path.dirname(__file__), filename)): found = os.path.join(os.path.dirname(__file__), filename) if found is None: # give up in disgust. raise ImportError, \ "No system module '%s' (%s)" % (modname, filename) # Python can load the module mod = imp.load_module(modname, None, found, ('.dll', 'rb', imp.C_EXTENSION)) # and fill our namespace with it. globs.update(mod.__dict__)
def __import_pywin32_system_module__(modname, globs): # This has been through a number of iterations. The problem: how to # locate pywintypesXX.dll when it may be in a number of places, and how # to avoid ever loading it twice. This problem is compounded by the # fact that the "right" way to do this requires win32api, but this # itself requires pywintypesXX. # And the killer problem is that someone may have done 'import win32api' # before this code is called. In that case Windows will have already # loaded pywintypesXX as part of loading win32api - but by the time # we get here, we may locate a different one. This appears to work, but # then starts raising bizarre TypeErrors complaining that something # is not a pywintypes type when it clearly is! # So in what we hope is the last major iteration of this, we now # rely on a _win32sysloader module, implemented in C but not relying # on pywintypesXX.dll. It then can check if the DLL we are looking for # lib is already loaded. if not sys.platform.startswith("win32"): # These extensions can be built on Linux via the 'mainwin' toolkit. # Look for a native 'lib{modname}.so' # NOTE: The _win32sysloader module will probably build in this # environment, so it may be better to use that here too. for ext, mode, ext_type in imp.get_suffixes(): if ext_type == imp.C_EXTENSION: for path in sys.path: look = os.path.join(path, "lib" + modname + ext) if os.path.isfile(look): mod = imp.load_module(modname, None, look, (ext, mode, ext_type)) # and fill our namespace with it. # XXX - if this ever moves to py3k, this will probably # need similar adjustments as below... globs.update(mod.__dict__) return raise ImportError("No dynamic module " + modname) # See if this is a debug build. for suffix_item in imp.get_suffixes(): if suffix_item[0] == '_d.pyd': suffix = '_d' break else: suffix = "" filename = "%s%d%d%s.dll" % \ (modname, sys.version_info[0], sys.version_info[1], suffix) if hasattr(sys, "frozen"): # If we are running from a frozen program (py2exe, McMillan, freeze) # then we try and load the DLL from our sys.path # XXX - This path may also benefit from _win32sysloader? However, # MarkH has never seen the DLL load problem with py2exe programs... for look in sys.path: # If the sys.path entry is a (presumably) .zip file, use the # directory if os.path.isfile(look): look = os.path.dirname(look) found = os.path.join(look, filename) if os.path.isfile(found): break else: raise ImportError("Module '%s' isn't in frozen sys.path %s" % (modname, sys.path)) else: # First see if it already in our process - if so, we must use that. import _win32sysloader found = _win32sysloader.GetModuleFilename(filename) if found is None: # We ask Windows to load it next. This is in an attempt to # get the exact same module loaded should pywintypes be imported # first (which is how we are here) or if, eg, win32api was imported # first thereby implicitly loading the DLL. # Sadly though, it doesn't quite work - if pywintypesxx.dll # is in system32 *and* the executable's directory, on XP SP2, an # import of win32api will cause Windows to load pywintypes # from system32, where LoadLibrary for that name will # load the one in the exe's dir. # That shouldn't really matter though, so long as we only ever # get one loaded. found = _win32sysloader.LoadModule(filename) if found is None: # Windows can't find it - which although isn't relevent here, # means that we *must* be the first win32 import, as an attempt # to import win32api etc would fail when Windows attempts to # locate the DLL. # This is most likely to happen for "non-admin" installs, where # we can't put the files anywhere else on the global path. # If there is a version in our Python directory, use that if os.path.isfile(os.path.join(sys.prefix, filename)): found = os.path.join(sys.prefix, filename) if found is None: # Not in the Python directory? Maybe we were installed via # easy_install... if os.path.isfile(os.path.join(os.path.dirname(__file__), filename)): found = os.path.join(os.path.dirname(__file__), filename) if found is None: # We might have been installed via PIP and without the post-install # script having been run, so they might be in the # lib/site-packages/pywin32_system32 directory. # This isn't ideal as it means, say 'python -c "import win32api"' # will not work but 'python -c "import pywintypes, win32api"' will, # but it's better than nothing... import distutils.sysconfig maybe = os.path.join( distutils.sysconfig.get_python_lib(plat_specific=1), "pywin32_system32", filename) if os.path.isfile(maybe): found = maybe if found is None: # give up in disgust. raise ImportError("No system module '%s' (%s)" % (modname, filename)) # py2k and py3k differences: # On py2k, after doing "imp.load_module('pywintypes')", sys.modules # is unchanged - ie, sys.modules['pywintypes'] still refers to *this* # .py module - but the module's __dict__ has *already* need updated # with the new module's contents. # However, on py3k, sys.modules *is* changed - sys.modules['pywintypes'] # will be changed to the new module object. # SO: * on py2k don't need to update any globals. # * on py3k we update our module dict with the new module's dict and # copy its globals to ours. old_mod = sys.modules[modname] # Python can load the module mod = imp.load_dynamic(modname, found) # Check the sys.modules[] behaviour we describe above is true... if sys.version_info < (3, 0): assert sys.modules[modname] is old_mod assert mod is old_mod else: assert sys.modules[modname] is not old_mod assert sys.modules[modname] is mod # as above - re-reset to the *old* module object then update globs. sys.modules[modname] = old_mod globs.update(mod.__dict__)
def __import_pywin32_system_module__(modname, globs): # This has been through a number of iterations. The problem: how to # locate pywintypesXX.dll when it may be in a number of places, and how # to avoid ever loading it twice. This problem is compounded by the # fact that the "right" way to do this requires win32api, but this # itself requires pywintypesXX. # And the killer problem is that someone may have done 'import win32api' # before this code is called. In that case Windows will have already # loaded pywintypesXX as part of loading win32api - but by the time # we get here, we may locate a different one. This appears to work, but # then starts raising bizarre TypeErrors complaining that something # is not a pywintypes type when it clearly is! # So in what we hope is the last major iteration of this, we now # rely on a _win32sysloader module, implemented in C but not relying # on pywintypesXX.dll. It then can check if the DLL we are looking for # lib is already loaded. # See if this is a debug build. suffix = "_d" if "_d.pyd" in importlib.machinery.EXTENSION_SUFFIXES else "" filename = "%s%d%d%s.dll" % ( modname, sys.version_info[0], sys.version_info[1], suffix, ) if hasattr(sys, "frozen"): # If we are running from a frozen program (py2exe, McMillan, freeze) # then we try and load the DLL from our sys.path # XXX - This path may also benefit from _win32sysloader? However, # MarkH has never seen the DLL load problem with py2exe programs... for look in sys.path: # If the sys.path entry is a (presumably) .zip file, use the # directory if os.path.isfile(look): look = os.path.dirname(look) found = os.path.join(look, filename) if os.path.isfile(found): break else: raise ImportError("Module '%s' isn't in frozen sys.path %s" % (modname, sys.path)) else: # First see if it already in our process - if so, we must use that. import _win32sysloader found = _win32sysloader.GetModuleFilename(filename) if found is None: # We ask Windows to load it next. This is in an attempt to # get the exact same module loaded should pywintypes be imported # first (which is how we are here) or if, eg, win32api was imported # first thereby implicitly loading the DLL. # Sadly though, it doesn't quite work - if pywintypesxx.dll # is in system32 *and* the executable's directory, on XP SP2, an # import of win32api will cause Windows to load pywintypes # from system32, where LoadLibrary for that name will # load the one in the exe's dir. # That shouldn't really matter though, so long as we only ever # get one loaded. found = _win32sysloader.LoadModule(filename) if found is None: # Windows can't find it - which although isn't relevent here, # means that we *must* be the first win32 import, as an attempt # to import win32api etc would fail when Windows attempts to # locate the DLL. # This is most likely to happen for "non-admin" installs, where # we can't put the files anywhere else on the global path. # If there is a version in our Python directory, use that if os.path.isfile(os.path.join(sys.prefix, filename)): found = os.path.join(sys.prefix, filename) if found is None: # Not in the Python directory? Maybe we were installed via # easy_install... if os.path.isfile(os.path.join(os.path.dirname(__file__), filename)): found = os.path.join(os.path.dirname(__file__), filename) if found is None: # We might have been installed via PIP and without the post-install # script having been run, so they might be in the # lib/site-packages/pywin32_system32 directory. # This isn't ideal as it means, say 'python -c "import win32api"' # will not work but 'python -c "import pywintypes, win32api"' will, # but it's better than nothing... import sysconfig maybe = os.path.join(sysconfig.get_paths()["platlib"], "pywin32_system32", filename) if os.path.isfile(maybe): found = maybe if found is None: # give up in disgust. raise ImportError("No system module '%s' (%s)" % (modname, filename)) # After importing the module, sys.modules is updated to the DLL we just # loaded - which isn't what we want. So we update sys.modules to refer to # this module, and update our globals from it. old_mod = sys.modules[modname] # Load the DLL. loader = importlib.machinery.ExtensionFileLoader(modname, found) spec = importlib.machinery.ModuleSpec(name=modname, loader=loader, origin=found) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) # Check the sys.modules[] behaviour we describe above is true... assert sys.modules[modname] is not old_mod assert sys.modules[modname] is mod # as above - re-reset to the *old* module object then update globs. sys.modules[modname] = old_mod globs.update(mod.__dict__)
try: import _win32sysloader except: raise Exception("Cannot import PyWin32. Are you sure it's installed?") # Anaconda and possibly other distributions have a bug in PyWin32, the `pythoncom` module can't be loaded because some required # DLLs are located in the wrong place, so they aren't found. This code forces Windows to load them with the full path so that # subsequent imports work correctly import sys import os pywintypes_filename = "pywintypes%d%d.dll" % (sys.version_info[0], sys.version_info[1]) pywintypes_found = _win32sysloader.GetModuleFilename(pywintypes_filename) if not pywintypes_found: pywintypes_found = _win32sysloader.LoadModule( os.path.join(sys.prefix, 'lib', 'site-packages', 'win32', pywintypes_filename)) # Import necessary modules import types import pythoncom import pywintypes import win32com.client import win32com.server.util as serverutil import win32com.server.dispatcher import win32com.server.policy import win32api import winerror # --- XLPython object class id ---