Python 64 bit DLL COM Server Registration Problem

2019-08-13 22:48发布

问题:

I am trying to create a simple COM server using Python 2.7 on 64 bit Windows 7, but I can't get the DLL registered successfully. I am able to do this successfully using Python 2.6 on 32 bit Windows XP. I am also able to register my class directly from Python.

This is my module, heikki.py, based on the pywin32 COM tutorial:

class Heikki:
  _reg_clsid_ = '{F4C7D945-BF6B-4BF8-BCBB-EA021FCCE623}'
  _reg_desc_ = "Heikki"
  _reg_progid_ = "Heikki.TestServer"
  _public_methods_ = ['Hello']

  def __init__(self):
      pass

  def Hello(self):
      return 1

if __name__=='__main__':
    from win32com.server import register
    register.UseCommandLine(Heikki)

I can register it successfully from the command line like so (I have 64 bit Python 2.7.1, pywin32 214, py2exe 0.6.9, c:\python27 is in PATH):

C:\temp> python heikki.py
Registered : Heikki.TestServer

C:\temp> python heikki.py --unregister
Unregistered : Heikki.TestServer

I then created a setup.py file based on a py2exe COM server sample at c:\temp:

from distutils.core import setup
import py2exe

class Target:
    def __init__(self, **kw):
        self.__dict__.update(kw)
        # for the version info resources (Properties -- Version)
        self.version = "1.0"
        self.company_name = "My name"
        self.copyright = "(C) 2011, My company"
        self.name = "heikki"

heikki_target = Target(
    description = "my com server desc",
    # use module name for win32com exe/dll server
    modules = ["heikki"],
    # specify which type of com server you want (exe and/or dll)
    create_exe = False,
    create_dll = True
    )

setup(
    version = "1.0",
    zipfile=None,
    description = "my com server",
    name = "heikki",
    author="Heikki",
    com_server = [heikki_target],
    )

I then create the DLL:

c:\temp> python setup.py py2exe

However, this caused error message:

The following modules appear to be missing
['win32com.gen_py', 'win32com.shell', 'win32com.shell.shell']

Which I partially fixed by prepending the following to the setup script:

import sys

if 1:
 try:
    import py2exe.mf as modulefinder
 except ImportError:
    import modulefinder
 import win32com
 for p in win32com.__path__[1:]:
     modulefinder.AddPackagePath("win32com", p)
 for extra in ["win32com.shell"]:
    __import__(extra)
    m = sys.modules[extra]
    for p in m.__path__[1:]:
        modulefinder.AddPackagePath(extra, p)

but I still get:

The following modules appear to be missing
['win32com.gen_py']

I read that in some cases this error can be ignored, so I pressed on. At this point my dist dir looks like this:

07/13/2009  05:24 PM             3,072 API-MS-Win-Core-ErrorHandling-L1-1-0.dll
07/13/2009  05:24 PM             3,584 API-MS-Win-Core-LibraryLoader-L1-1-0.dll
07/13/2009  05:24 PM             4,096 API-MS-Win-Core-LocalRegistry-L1-1-0.dll
07/13/2009  05:24 PM             3,584 API-MS-Win-Core-Misc-L1-1-0.dll
07/13/2009  05:24 PM             4,608 API-MS-Win-Core-ProcessThreads-L1-1-0.dll
07/13/2009  05:24 PM             3,072 API-MS-Win-Core-Profile-L1-1-0.dll
07/13/2009  05:24 PM             4,096 API-MS-Win-Core-Synch-L1-1-0.dll
07/13/2009  05:24 PM             4,096 API-MS-Win-Core-SysInfo-L1-1-0.dll
07/13/2009  05:24 PM             6,144 API-MS-Win-Security-Base-L1-1-0.dll
11/27/2010  05:19 PM            80,384 bz2.pyd
07/13/2009  05:40 PM           207,360 CFGMGR32.dll
07/13/2009  05:40 PM            93,184 DEVOBJ.dll
01/06/2011  12:07 PM         2,363,665 heikki.dll
07/13/2009  05:41 PM           421,376 KERNELBASE.dll
11/06/2007  03:02 PM         1,671,160 mfc90.dll
07/13/2009  05:41 PM           167,424 POWRPROF.dll
11/27/2010  05:19 PM         2,978,816 python27.dll
07/05/2009  04:56 AM           489,984 pythoncom27.dll
07/05/2009  04:54 AM           138,240 pywintypes27.dll
11/27/2010  05:19 PM            10,752 select.pyd
07/13/2009  05:41 PM         1,899,520 SETUPAPI.dll
11/27/2010  05:19 PM           689,664 unicodedata.pyd
07/05/2009  04:55 AM           125,440 win32api.pyd
07/05/2009  04:58 AM           354,816 win32com.shell.shell.pyd
07/05/2009  04:54 AM            21,504 win32event.pyd
07/05/2009  04:54 AM            44,032 win32process.pyd
07/05/2009  04:54 AM            18,432 win32trace.pyd
07/05/2009  05:00 AM         1,034,752 win32ui.pyd
07/05/2009  04:55 AM           236,544 winxpgui.pyd
11/27/2010  05:22 PM           471,552 _hashlib.pyd
07/05/2009  04:54 AM             9,216 _win32sysloader.pyd

So I try to register the DLL:

c:\temp\dist> regsvr32 heikki.dll

but this pops up a dialog that says:

The module "heikki.dll" was loaded but the call to
DllRegisterServer failed with error code 0x80040201

According to MS KB:

There was an error when regsvr32.exe invoked the entrypoint in the module specified in the command line.

I then turn to Dependency Walker which gives me 2 warnings for heikki.dll:

IEFRAME.DLL
SHLWAPI.DLL

The latter one I can double click into to get more info, the first one says:

Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.

I then used Dependency Walker on regsrv32; just opening regsvr32 gave warnings for the same files. Profiling heikki.dll gave errors for:

<empty string>
ZLIB.PYD

On some attemps I also got an error for ieshims.dll, but I added the Internet Explorer dir to PATH and copied the DLL to dist and got away with that error. The Dependency Walker says this about the <empty string> error:

which means GetProcAddress was called with an empty string

I would also hope that the zlib.pyd error is harmless, because there should be no more need for zlib.pyd given that it should be builtin AFAIK. I tried dropping zlib1.dll as zlib.pyd in my dist dir, but while this gets rid of the DDL import error there is another error about the pyd file not having an expected entry point (initzlib or something, forgot).

I haven't been able to get rid of the gen_py warning from py2exe in my tries either. I've tried various tweaks to the setup.py file as well as heikki.py module, but with no success.

At this point I am running out of ideas to look into.

回答1:

This looks like a duplicate of Com server build using Python on 64-bit Windows 7 machine.

Add "import win32traceutil" to the top of heikki.py and run C:\Python27\Lib\site-packages\win32\lib\win32traceutil.py in a second Python process to see the traceback from heikki.dll:

Traceback (most recent call last):
  File "boot_com_servers.py", line 37, in <module>
pywintypes.error: (126, 'GetModuleFileName', 'The specified module could not be found.')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'DllRegisterServer' is not defined

Update:

There's a bug in py2exe on 64 bit Python. The sys.frozendllhandle, initialized by py2exe, is invalid such that win32api.GetModuleFileName(sys.frozendllhandle) fails.

You might want to try the patched py2exe installers at http://www.lfd.uci.edu/~gohlke/pythonlibs/#py2exe