Recipe 10.12. Registering or Unregistering a DLL on Windows
Credit: Bill Bell
Problem
You want to register or unregister a
DLL in Windows, just as it is normally done by
regsrv32.exe, but you want to do it from Python,
without requiring that executable to be present or bothering to find
it.
Solution
All that Microsoft's
regsrv32.exe does is load a DLL and call its
entries named DllRegisterServer or
DllUnregisterServer. This behavior is very easy to
replicate via Thomas Heller's
ctypes extension:
from ctypes import windllThe
dll = windll[r'C:\Path\To\Some.DLL']
result = dll.DllRegisterServer( )
result = dll.DllUnregisterServer( )
result is of Windows type
HRESULT, so, if you wish,
ctypes can also implicitly check it for you,
raising a ctypes.WindowsError exception when an
error occurs; you just need to use ctypes.oledll
instead of ctypes.windll. In other words, to have
the result automatically checked and an exception raised in case of
errors, instead of the previous script, use this one:
from ctypes import oledll
dll = oledll[r'C:\Path\To\Some.DLL']
dll.DllRegisterServer( )
dll.DllUnregisterServer( )
Discussion
Thomas Heller's ctypes enables
your Python code to load DLLs on Windows (and similar dynamic/shared
libraries on other platforms) and call functions from such libraries,
and it manages to perform these tasks with a high degree of both
power and elegance. On Windows, in particular, it offers even further
"added value" through such
mechanisms as the oledll object, which, besides
loading DLLs and calling functions from them, also checks the
returned hrESULT instances and raises appropriate
exceptions when the HRESULT values indicate
errors. In this recipe,
we're using ctypes (either the
windll or oledll objects from
that module) specifically to avoid the need to use
Microsoft's regsrv32.exe to
register or unregister DLLs that implement in-process COM servers for
some CLSIDs. (A CLSID is a globally unique identifier that identifies
a COM class object, and the abbreviation presumably stands for class
identifier.) The cases in which you'll use this
specific recipe are only those in which you need to register or
unregister such COM DLLs (whether they're
implemented in Python or otherwise makes no difference). Be aware,
however, that the applicability of ctypes is far
wider, as it extends to any case in which you wish your Python code
to load and interact with a DLL (or, on platforms other than Windows,
equivalent dynamically loaded libraries, such as
.so files on Linux and
.dynlib files on Mac OS
X).The protocol that regsrv32.exe implements is
well documented and very simple, so our own code can reimplement it
in a jiffy. That's much more practical than
requiring regsrv32.exe to be installed on the
machine on which we want to register or unregister the DLLs, not to
mention finding where the EXE file might be to run it directly (via
os.spawn or whatever) and also finding an
effective way to detect errors and show them to the user.
See Also
ctypes is at http://sourceforge.net/projects/ctypes.