You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.3 KiB
69 lines
2.3 KiB
6 years ago
|
from ctypes import *
|
||
|
import comtypes
|
||
|
from comtypes.hresult import *
|
||
|
from comtypes.server import IClassFactory
|
||
|
import logging
|
||
|
import queue
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
_debug = logger.debug
|
||
|
|
||
|
REGCLS_SINGLEUSE = 0 # class object only generates one instance
|
||
|
REGCLS_MULTIPLEUSE = 1 # same class object genereates multiple inst.
|
||
|
REGCLS_MULTI_SEPARATE = 2 # multiple use, but separate control over each
|
||
|
REGCLS_SUSPENDED = 4 # register it as suspended, will be activated
|
||
|
REGCLS_SURROGATE = 8 # must be used when a surrogate process
|
||
|
|
||
|
def run(classes):
|
||
|
classobjects = [ClassFactory(cls) for cls in classes]
|
||
|
comtypes.COMObject.__run_localserver__(classobjects)
|
||
|
|
||
|
class ClassFactory(comtypes.COMObject):
|
||
|
_com_interfaces_ = [IClassFactory]
|
||
|
_locks = 0
|
||
|
_queue = None
|
||
|
regcls = REGCLS_MULTIPLEUSE
|
||
|
|
||
|
def __init__(self, cls, *args, **kw):
|
||
|
super(ClassFactory, self).__init__()
|
||
|
self._cls = cls
|
||
|
self._register_class()
|
||
|
self._args = args
|
||
|
self._kw = kw
|
||
|
|
||
|
def IUnknown_AddRef(self, this):
|
||
|
return 2
|
||
|
|
||
|
def IUnknown_Release(self, this):
|
||
|
return 1
|
||
|
|
||
|
def _register_class(self):
|
||
|
regcls = getattr(self._cls, "_regcls_", self.regcls)
|
||
|
cookie = c_ulong()
|
||
|
ptr = self._com_pointers_[comtypes.IUnknown._iid_]
|
||
|
clsctx = self._cls._reg_clsctx_
|
||
|
clsctx &= ~comtypes.CLSCTX_INPROC # reset the inproc flags
|
||
|
oledll.ole32.CoRegisterClassObject(byref(comtypes.GUID(self._cls._reg_clsid_)),
|
||
|
ptr,
|
||
|
clsctx,
|
||
|
regcls,
|
||
|
byref(cookie))
|
||
|
self.cookie = cookie
|
||
|
|
||
|
def _revoke_class(self):
|
||
|
oledll.ole32.CoRevokeClassObject(self.cookie)
|
||
|
|
||
|
def CreateInstance(self, this, punkOuter, riid, ppv):
|
||
|
_debug("ClassFactory.CreateInstance(%s)", riid[0])
|
||
|
obj = self._cls(*self._args, **self._kw)
|
||
|
result = obj.IUnknown_QueryInterface(None, riid, ppv)
|
||
|
_debug("CreateInstance() -> %s", result)
|
||
|
return result
|
||
|
|
||
|
def LockServer(self, this, fLock):
|
||
|
if fLock:
|
||
|
comtypes.COMObject.__server__.Lock()
|
||
|
else:
|
||
|
comtypes.COMObject.__server__.Unlock()
|
||
|
return S_OK
|