connect.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. """Utilities for Server Side connections.
  2. A collection of helpers for server side connection points.
  3. """
  4. import pythoncom
  5. from .exception import Exception
  6. import winerror
  7. from win32com import olectl
  8. import win32com.server.util
  9. # Methods implemented by the interfaces.
  10. IConnectionPointContainer_methods = ["EnumConnectionPoints","FindConnectionPoint"]
  11. IConnectionPoint_methods = ["EnumConnections","Unadvise","Advise","GetConnectionPointContainer","GetConnectionInterface"]
  12. class ConnectableServer:
  13. _public_methods_ = IConnectionPointContainer_methods + IConnectionPoint_methods
  14. _com_interfaces_ = [pythoncom.IID_IConnectionPoint, pythoncom.IID_IConnectionPointContainer]
  15. # Clients must set _connect_interfaces_ = [...]
  16. def __init__(self):
  17. self.cookieNo = 0
  18. self.connections = {}
  19. # IConnectionPoint interfaces
  20. def EnumConnections(self):
  21. raise Exception(winerror.E_NOTIMPL)
  22. def GetConnectionInterface(self):
  23. raise Exception(winerror.E_NOTIMPL)
  24. def GetConnectionPointContainer(self):
  25. return win32com.server.util.wrap(self)
  26. def Advise(self, pUnk):
  27. # Creates a connection to the client. Simply allocate a new cookie,
  28. # find the clients interface, and store it in a dictionary.
  29. try:
  30. interface = pUnk.QueryInterface(self._connect_interfaces_[0],pythoncom.IID_IDispatch)
  31. except pythoncom.com_error:
  32. raise Exception(scode=olectl.CONNECT_E_NOCONNECTION)
  33. self.cookieNo = self.cookieNo + 1
  34. self.connections[self.cookieNo] = interface
  35. return self.cookieNo
  36. def Unadvise(self, cookie):
  37. # Destroy a connection - simply delete interface from the map.
  38. try:
  39. del self.connections[cookie]
  40. except KeyError:
  41. raise Exception(scode=winerror.E_UNEXPECTED)
  42. # IConnectionPointContainer interfaces
  43. def EnumConnectionPoints(self):
  44. raise Exception(winerror.E_NOTIMPL)
  45. def FindConnectionPoint(self, iid):
  46. # Find a connection we support. Only support the single event interface.
  47. if iid in self._connect_interfaces_:
  48. return win32com.server.util.wrap(self)
  49. def _BroadcastNotify(self, broadcaster, extraArgs):
  50. # Broadcasts a notification to all connections.
  51. # Ignores clients that fail.
  52. for interface in self.connections.values():
  53. try:
  54. broadcaster(*(interface,)+extraArgs)
  55. except pythoncom.com_error as details:
  56. self._OnNotifyFail(interface, details)
  57. def _OnNotifyFail(self, interface, details):
  58. print("Ignoring COM error to connection - %s" % (repr(details)))