Todo: 集成多平台 解决因SaiNiu线程抢占资源问题 本地提交测试环境打包 和 正式打包脚本与正式环境打包bat 提交Python32环境包 改进多日志文件生成情况修改打包日志细节
This commit is contained in:
229
Utils/PythonNew32/Lib/site-packages/win32com/server/util.py
Normal file
229
Utils/PythonNew32/Lib/site-packages/win32com/server/util.py
Normal file
@@ -0,0 +1,229 @@
|
||||
"""General Server side utilities"""
|
||||
|
||||
import pythoncom
|
||||
import winerror
|
||||
|
||||
from . import policy
|
||||
from .exception import COMException
|
||||
|
||||
|
||||
def wrap(ob, iid=None, usePolicy=None, useDispatcher=None):
|
||||
"""Wraps an object in a PyGDispatch gateway.
|
||||
|
||||
Returns a client side PyI{iid} interface.
|
||||
|
||||
Interface and gateway support must exist for the specified IID, as
|
||||
the QueryInterface() method is used.
|
||||
|
||||
"""
|
||||
if usePolicy is None:
|
||||
usePolicy = policy.DefaultPolicy
|
||||
if useDispatcher == 1: # True will also work here.
|
||||
import win32com.server.dispatcher
|
||||
|
||||
useDispatcher = win32com.server.dispatcher.DefaultDebugDispatcher
|
||||
if useDispatcher is None or useDispatcher == 0:
|
||||
ob = usePolicy(ob)
|
||||
else:
|
||||
ob = useDispatcher(usePolicy, ob)
|
||||
|
||||
# get a PyIDispatch, which interfaces to PyGDispatch
|
||||
ob = pythoncom.WrapObject(ob)
|
||||
if iid is not None:
|
||||
ob = ob.QueryInterface(iid) # Ask the PyIDispatch if it supports it?
|
||||
return ob
|
||||
|
||||
|
||||
def unwrap(ob):
|
||||
"""Unwraps an interface.
|
||||
|
||||
Given an interface which wraps up a Gateway, return the object behind
|
||||
the gateway.
|
||||
"""
|
||||
ob = pythoncom.UnwrapObject(ob)
|
||||
# see if the object is a dispatcher
|
||||
if hasattr(ob, "policy"):
|
||||
ob = ob.policy
|
||||
return ob._obj_
|
||||
|
||||
|
||||
class ListEnumerator:
|
||||
"""A class to expose a Python sequence as an EnumVARIANT.
|
||||
|
||||
Create an instance of this class passing a sequence (list, tuple, or
|
||||
any sequence protocol supporting object) and it will automatically
|
||||
support the EnumVARIANT interface for the object.
|
||||
|
||||
See also the @NewEnum@ function, which can be used to turn the
|
||||
instance into an actual COM server.
|
||||
"""
|
||||
|
||||
_public_methods_ = ["Next", "Skip", "Reset", "Clone"]
|
||||
|
||||
def __init__(self, data, index=0, iid=pythoncom.IID_IEnumVARIANT):
|
||||
self._list_ = data
|
||||
self.index = index
|
||||
self._iid_ = iid
|
||||
|
||||
def _query_interface_(self, iid):
|
||||
if iid == self._iid_:
|
||||
return 1
|
||||
|
||||
def Next(self, count):
|
||||
result = self._list_[self.index : self.index + count]
|
||||
self.Skip(count)
|
||||
return result
|
||||
|
||||
def Skip(self, count):
|
||||
end = self.index + count
|
||||
if end > len(self._list_):
|
||||
end = len(self._list_)
|
||||
self.index = end
|
||||
|
||||
def Reset(self):
|
||||
self.index = 0
|
||||
|
||||
def Clone(self):
|
||||
return self._wrap(self.__class__(self._list_, self.index))
|
||||
|
||||
def _wrap(self, ob):
|
||||
return wrap(ob)
|
||||
|
||||
|
||||
class ListEnumeratorGateway(ListEnumerator):
|
||||
"""A List Enumerator which wraps a sequence's items in gateways.
|
||||
|
||||
If a sequence contains items (objects) that have not been wrapped for
|
||||
return through the COM layers, then a ListEnumeratorGateway can be
|
||||
used to wrap those items before returning them (from the Next() method).
|
||||
|
||||
See also the @ListEnumerator@ class and the @NewEnum@ function.
|
||||
"""
|
||||
|
||||
def Next(self, count):
|
||||
result = self._list_[self.index : self.index + count]
|
||||
self.Skip(count)
|
||||
return map(self._wrap, result)
|
||||
|
||||
|
||||
def NewEnum(
|
||||
seq,
|
||||
cls=ListEnumerator,
|
||||
iid=pythoncom.IID_IEnumVARIANT,
|
||||
usePolicy=None,
|
||||
useDispatcher=None,
|
||||
):
|
||||
"""Creates a new enumerator COM server.
|
||||
|
||||
This function creates a new COM Server that implements the
|
||||
IID_IEnumVARIANT interface.
|
||||
|
||||
A COM server that can enumerate the passed in sequence will be
|
||||
created, then wrapped up for return through the COM framework.
|
||||
Optionally, a custom COM server for enumeration can be passed
|
||||
(the default is @ListEnumerator@), and the specific IEnum
|
||||
interface can be specified.
|
||||
"""
|
||||
ob = cls(seq, iid=iid)
|
||||
return wrap(ob, iid, usePolicy=usePolicy, useDispatcher=useDispatcher)
|
||||
|
||||
|
||||
class Collection:
|
||||
"A collection of VARIANT values."
|
||||
|
||||
_public_methods_ = ["Item", "Count", "Add", "Remove", "Insert"]
|
||||
|
||||
def __init__(self, data=None, readOnly=0):
|
||||
if data is None:
|
||||
data = []
|
||||
self.data = data
|
||||
|
||||
# disable Add/Remove if read-only. note that we adjust _public_methods_
|
||||
# on this instance only.
|
||||
if readOnly:
|
||||
self._public_methods_ = ["Item", "Count"]
|
||||
|
||||
# This method is also used as the "default" method.
|
||||
# Thus "print(ob)" will cause this to be called with zero
|
||||
# params. Handle this slightly more elegantly here.
|
||||
# Ideally the policy should handle this.
|
||||
def Item(self, *args):
|
||||
if len(args) != 1:
|
||||
raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT)
|
||||
|
||||
try:
|
||||
return self.data[args[0]]
|
||||
except IndexError as desc:
|
||||
raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))
|
||||
|
||||
_value_ = Item
|
||||
|
||||
def Count(self):
|
||||
return len(self.data)
|
||||
|
||||
def Add(self, value):
|
||||
self.data.append(value)
|
||||
|
||||
def Remove(self, index):
|
||||
try:
|
||||
del self.data[index]
|
||||
except IndexError as desc:
|
||||
raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))
|
||||
|
||||
def Insert(self, index, value):
|
||||
try:
|
||||
index = int(index)
|
||||
except (ValueError, TypeError):
|
||||
raise COMException(scode=winerror.DISP_E_TYPEMISMATCH)
|
||||
self.data.insert(index, value)
|
||||
|
||||
def _NewEnum(self):
|
||||
return NewEnum(self.data)
|
||||
|
||||
|
||||
def NewCollection(seq, cls=Collection):
|
||||
"""Creates a new COM collection object
|
||||
|
||||
This function creates a new COM Server that implements the
|
||||
common collection protocols, including enumeration. (_NewEnum)
|
||||
|
||||
A COM server that can enumerate the passed in sequence will be
|
||||
created, then wrapped up for return through the COM framework.
|
||||
Optionally, a custom COM server for enumeration can be passed
|
||||
(the default is @Collection@).
|
||||
"""
|
||||
return pythoncom.WrapObject(
|
||||
policy.DefaultPolicy(cls(seq)), pythoncom.IID_IDispatch, pythoncom.IID_IDispatch
|
||||
)
|
||||
|
||||
|
||||
class FileStream:
|
||||
_public_methods_ = ["Read", "Write", "Clone", "CopyTo", "Seek"]
|
||||
_com_interfaces_ = [pythoncom.IID_IStream]
|
||||
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
|
||||
def Read(self, amount):
|
||||
return self.file.read(amount)
|
||||
|
||||
def Write(self, data):
|
||||
self.file.write(data)
|
||||
return len(data)
|
||||
|
||||
def Clone(self):
|
||||
return self._wrap(self.__class__(self.file))
|
||||
|
||||
def CopyTo(self, dest, cb):
|
||||
data = self.file.read(cb)
|
||||
cbread = len(data)
|
||||
dest.Write(data) ## ??? Write does not currently return the length ???
|
||||
return cbread, cbread
|
||||
|
||||
def Seek(self, offset, origin):
|
||||
# how convient that the 'origin' values are the same as the CRT :)
|
||||
self.file.seek(offset, origin)
|
||||
return self.file.tell()
|
||||
|
||||
def _wrap(self, ob):
|
||||
return wrap(ob)
|
||||
Reference in New Issue
Block a user