comtypes 1.4.8__zip → 1.4.10__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. {comtypes-1.4.8 → comtypes-1.4.10}/CHANGES.txt +40 -0
  2. {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.10}/PKG-INFO +4 -3
  3. {comtypes-1.4.8 → comtypes-1.4.10}/README.md +1 -1
  4. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/GUID.py +38 -16
  5. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/__init__.py +36 -16
  6. comtypes-1.4.10/comtypes/_comobject.py +562 -0
  7. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_memberspec.py +93 -13
  8. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_meta.py +1 -0
  9. comtypes-1.4.10/comtypes/_post_coinit/_cominterface_meta_patcher.py +152 -0
  10. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/bstr.py +12 -5
  11. comtypes-1.4.8/comtypes/_py_instance_method.py → comtypes-1.4.10/comtypes/_post_coinit/instancemethod.py +1 -2
  12. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/misc.py +60 -25
  13. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/unknwn.py +26 -176
  14. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_safearray.py +3 -4
  15. comtypes-1.4.10/comtypes/_vtbl.py +448 -0
  16. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/automation.py +46 -49
  17. comtypes-1.4.10/comtypes/client/__init__.py +42 -0
  18. comtypes-1.4.10/comtypes/client/_activeobj.py +46 -0
  19. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_code_cache.py +10 -5
  20. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_constants.py +1 -1
  21. comtypes-1.4.10/comtypes/client/_create.py +147 -0
  22. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_events.py +58 -13
  23. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_generate.py +7 -11
  24. comtypes-1.4.10/comtypes/client/_managing.py +114 -0
  25. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/dynamic.py +2 -3
  26. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/lazybind.py +12 -13
  27. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/connectionpoints.py +2 -1
  28. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/errorinfo.py +22 -9
  29. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/git.py +5 -5
  30. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hints.pyi +7 -15
  31. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/logutil.py +15 -3
  32. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/messageloop.py +1 -1
  33. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/persist.py +3 -5
  34. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/safearray.py +17 -5
  35. comtypes-1.4.10/comtypes/server/__init__.py +104 -0
  36. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/automation.py +1 -2
  37. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/connectionpoints.py +5 -5
  38. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/inprocserver.py +25 -17
  39. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/localserver.py +49 -19
  40. comtypes-1.4.10/comtypes/server/register.py +478 -0
  41. comtypes-1.4.10/comtypes/server/w_getopt.py +48 -0
  42. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/shelllink.py +16 -33
  43. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/stream.py +7 -4
  44. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.py +6 -7
  45. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.py +4 -2
  46. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/__init__.py +10 -12
  47. comtypes-1.4.10/comtypes/test/find_memleak.py +72 -0
  48. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/runtests.py +1 -0
  49. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/setup.py +2 -1
  50. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_BSTR.py +10 -23
  51. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_GUID.py +1 -0
  52. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_QueryService.py +1 -0
  53. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_agilent.py +4 -3
  54. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_avmc.py +1 -1
  55. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_basic.py +12 -6
  56. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_casesensitivity.py +3 -5
  57. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_clear_cache.py +1 -1
  58. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client.py +2 -2
  59. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_dynamic.py +2 -2
  60. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_regenerate_modules.py +2 -2
  61. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_collections.py +4 -4
  62. comtypes-1.4.10/comtypes/test/test_comobject.py +146 -0
  63. comtypes-1.4.10/comtypes/test/test_comserver.py +349 -0
  64. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_createwrappers.py +2 -4
  65. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_records.py +1 -1
  66. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_safearrays.py +1 -1
  67. comtypes-1.4.10/comtypes/test/test_dispinterface.py +153 -0
  68. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dyndispatch.py +1 -0
  69. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_excel.py +22 -12
  70. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_findgendir.py +1 -2
  71. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_getactiveobj.py +4 -4
  72. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ie.py +19 -9
  73. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ienum.py +2 -2
  74. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_imfattributes.py +13 -3
  75. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_inout_args.py +8 -5
  76. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_midl_safearray_create.py +14 -4
  77. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_monikers.py +23 -9
  78. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_msscript.py +2 -1
  79. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_npsupport.py +4 -4
  80. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_outparam.py +37 -14
  81. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_persist.py +2 -4
  82. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_recordinfo.py +1 -1
  83. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_safearray.py +1 -90
  84. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_sapi.py +4 -1
  85. comtypes-1.4.10/comtypes/test/test_server.py +350 -0
  86. comtypes-1.4.10/comtypes/test/test_server_register.py +524 -0
  87. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_shelllink.py +2 -3
  88. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_showevents.py +7 -17
  89. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_storage.py +12 -6
  90. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_stream.py +16 -5
  91. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_subinterface.py +4 -2
  92. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeannotator.py +1 -2
  93. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeinfo.py +19 -7
  94. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_urlhistory.py +7 -4
  95. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_variant.py +3 -19
  96. comtypes-1.4.10/comtypes/test/test_w_getopt.py +29 -0
  97. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_win32com_interop.py +80 -36
  98. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_wmi.py +0 -3
  99. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_word.py +1 -1
  100. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/codegenerator.py +166 -440
  101. comtypes-1.4.10/comtypes/tools/codegenerator/comments.py +79 -0
  102. comtypes-1.4.10/comtypes/tools/codegenerator/heads.py +192 -0
  103. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/helpers.py +11 -14
  104. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/namespaces.py +13 -5
  105. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/packing.py +4 -4
  106. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/typeannotator.py +19 -9
  107. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/tlbparser.py +22 -23
  108. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc.py +4 -8
  109. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc_base.py +2 -2
  110. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/typeinfo.py +159 -63
  111. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/viewobject.py +3 -9
  112. {comtypes-1.4.8 → comtypes-1.4.10/comtypes.egg-info}/PKG-INFO +4 -3
  113. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/SOURCES.txt +11 -3
  114. {comtypes-1.4.8 → comtypes-1.4.10}/pyproject.toml +12 -19
  115. comtypes-1.4.8/comtypes/_comobject.py +0 -833
  116. comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
  117. comtypes-1.4.8/comtypes/client/__init__.py +0 -323
  118. comtypes-1.4.8/comtypes/server/__init__.py +0 -70
  119. comtypes-1.4.8/comtypes/server/register.py +0 -431
  120. comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
  121. comtypes-1.4.8/comtypes/test/find_memleak.py +0 -76
  122. comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
  123. comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
  124. comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
  125. comtypes-1.4.8/comtypes/test/test_server.py +0 -354
  126. {comtypes-1.4.8 → comtypes-1.4.10}/LICENSE.txt +0 -0
  127. {comtypes-1.4.8 → comtypes-1.4.10}/MANIFEST.in +0 -0
  128. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_npsupport.py +0 -0
  129. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/__init__.py +0 -0
  130. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_tlib_version_checker.py +0 -0
  131. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/clear_cache.py +0 -0
  132. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hresult.py +0 -0
  133. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/patcher.py +0 -0
  134. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.idl +0 -0
  135. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.tlb +0 -0
  136. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.idl +0 -0
  137. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.tlb +0 -0
  138. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.idl +0 -0
  139. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.tlb +0 -0
  140. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mytypelib.idl +0 -0
  141. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_DISPPARAMS.py +0 -0
  142. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dict.py +0 -0
  143. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_jscript.js +0 -0
  144. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_pump_events.py +0 -0
  145. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/urlhist.tlb +0 -0
  146. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/__init__.py +0 -0
  147. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/__init__.py +0 -0
  148. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  149. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/util.py +0 -0
  150. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/dependency_links.txt +0 -0
  151. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/entry_points.txt +0 -0
  152. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/top_level.txt +0 -0
  153. {comtypes-1.4.8 → comtypes-1.4.10}/setup.cfg +0 -0
  154. {comtypes-1.4.8 → comtypes-1.4.10}/setup.py +0 -0
@@ -0,0 +1,42 @@
1
+ """comtypes.client - High level client level COM support package."""
2
+
3
+ import ctypes
4
+ import logging
5
+
6
+ from comtypes import automation
7
+ from comtypes.client import dynamic, lazybind # noqa
8
+ from comtypes.client._code_cache import _find_gen_dir
9
+ from comtypes.client._constants import Constants # noqa
10
+ from comtypes.client._events import GetEvents, PumpEvents, ShowEvents
11
+ from comtypes.client._generate import GetModule
12
+ from comtypes.client._managing import GetBestInterface, _manage, wrap_outparam # noqa
13
+ from comtypes.hresult import * # noqa
14
+
15
+ gen_dir = _find_gen_dir()
16
+ import comtypes.gen # noqa
17
+
18
+ ### for testing
19
+ ##gen_dir = None
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ # backwards compatibility:
25
+ wrap = GetBestInterface
26
+
27
+ # Should we do this for POINTER(IUnknown) also?
28
+ ctypes.POINTER(automation.IDispatch).__ctypes_from_outparam__ = wrap_outparam # type: ignore
29
+
30
+ from comtypes.client._activeobj import GetActiveObject
31
+ from comtypes.client._create import (
32
+ CoGetObject,
33
+ CreateObject,
34
+ GetClassObject,
35
+ )
36
+
37
+ # fmt: off
38
+ __all__ = [
39
+ "CreateObject", "GetActiveObject", "CoGetObject", "GetEvents",
40
+ "ShowEvents", "PumpEvents", "GetModule", "GetClassObject",
41
+ ]
42
+ # fmt: on
@@ -0,0 +1,46 @@
1
+ from typing import Any, Optional, Type, TypeVar, overload
2
+ from typing import Union as _UnionT
3
+
4
+ import comtypes
5
+ import comtypes.client.dynamic
6
+ from comtypes import GUID, CoClass, IUnknown, automation
7
+ from comtypes.client._managing import _manage
8
+
9
+ _T_IUnknown = TypeVar("_T_IUnknown", bound=IUnknown)
10
+
11
+
12
+ ################################################################
13
+ #
14
+ # Object creation
15
+ #
16
+ @overload
17
+ def GetActiveObject(progid: _UnionT[str, Type[CoClass], GUID]) -> Any: ...
18
+ @overload
19
+ def GetActiveObject(
20
+ progid: _UnionT[str, Type[CoClass], GUID], interface: Type[_T_IUnknown]
21
+ ) -> _T_IUnknown: ...
22
+ def GetActiveObject(
23
+ progid: _UnionT[str, Type[CoClass], GUID],
24
+ interface: Optional[Type[IUnknown]] = None,
25
+ dynamic: bool = False,
26
+ ) -> Any:
27
+ """Return a pointer to a running COM object that has been
28
+ registered with COM.
29
+
30
+ 'progid' may be a string like "Excel.Application",
31
+ a string specifying a clsid, a GUID instance, or an object with
32
+ a _clsid_ attribute which should be any of the above.
33
+ 'interface' allows to force a certain interface.
34
+ 'dynamic=True' will return a dynamic dispatch object.
35
+ """
36
+ clsid = GUID.from_progid(progid)
37
+ if dynamic:
38
+ if interface is not None:
39
+ raise ValueError("interface and dynamic are mutually exclusive")
40
+ interface = automation.IDispatch
41
+ elif interface is None:
42
+ interface = getattr(progid, "_com_interfaces_", [None])[0]
43
+ obj = comtypes.GetActiveObject(clsid, interface=interface)
44
+ if dynamic:
45
+ return comtypes.client.dynamic.Dispatch(obj)
46
+ return _manage(obj, clsid, interface=interface)
@@ -5,7 +5,12 @@ comtypes.gen package and returns a directory where generated code can
5
5
  be written to.
6
6
  """
7
7
 
8
- import ctypes, logging, os, sys, tempfile, types
8
+ import ctypes
9
+ import logging
10
+ import os
11
+ import sys
12
+ import tempfile
13
+ import types
9
14
  from ctypes import wintypes
10
15
 
11
16
  logger = logging.getLogger(__name__)
@@ -48,23 +53,23 @@ def _find_gen_dir():
48
53
  # check type of executable image to determine a subdirectory
49
54
  # where generated modules are placed.
50
55
  ftype = getattr(sys, "frozen", None)
51
- version_str = "%d%d" % sys.version_info[:2]
56
+ pymaj, pymin = sys.version_info[:2]
52
57
  if ftype == None:
53
58
  # Python script
54
- subdir = r"Python\Python%s\comtypes_cache" % version_str
59
+ subdir = rf"Python\Python{pymaj:d}{pymin:d}\comtypes_cache"
55
60
  basedir = _get_appdata_dir()
56
61
 
57
62
  elif ftype == "dll":
58
63
  # dll created with py2exe
59
64
  path = _get_module_filename(sys.frozendllhandle)
60
65
  base = os.path.splitext(os.path.basename(path))[0]
61
- subdir = r"comtypes_cache\%s-%s" % (base, version_str)
66
+ subdir = rf"comtypes_cache\{base}-{pymaj:d}{pymin:d}"
62
67
  basedir = tempfile.gettempdir()
63
68
 
64
69
  else: # ftype in ('windows_exe', 'console_exe')
65
70
  # exe created by py2exe
66
71
  base = os.path.splitext(os.path.basename(sys.executable))[0]
67
- subdir = r"comtypes_cache\%s-%s" % (base, version_str)
72
+ subdir = rf"comtypes_cache\{base}-{pymaj:d}{pymin:d}"
68
73
  basedir = tempfile.gettempdir()
69
74
 
70
75
  gen_dir = os.path.join(basedir, subdir)
@@ -118,7 +118,7 @@ class Constants(object):
118
118
  # XXX is necessary warning? should use logging?
119
119
  # import comtypes.tools
120
120
  # if comtypes.tools.__warn_on_munge__:
121
- # print("# Fixing keyword as VAR_CONST for %s" % name)
121
+ # print(f"# Fixing keyword as VAR_CONST for {name}")
122
122
  name += "_"
123
123
  members[name] = vdesc._.lpvarValue[0].value
124
124
  return _frozen_attr_dict(members)
@@ -0,0 +1,147 @@
1
+ import logging
2
+ from typing import TYPE_CHECKING, Any, Optional, Type, TypeVar, overload
3
+ from typing import Union as _UnionT
4
+
5
+ import comtypes
6
+ import comtypes.client.dynamic
7
+ from comtypes import COSERVERINFO, GUID, CoClass, IUnknown, automation
8
+ from comtypes.client._managing import _manage
9
+
10
+ if TYPE_CHECKING:
11
+ from comtypes import hints # type: ignore
12
+
13
+
14
+ _T_IUnknown = TypeVar("_T_IUnknown", bound=IUnknown)
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ ################################################################
19
+ #
20
+ # Object creation
21
+ #
22
+ if TYPE_CHECKING:
23
+
24
+ @overload
25
+ def GetClassObject(
26
+ progid: _UnionT[str, Type[CoClass], GUID],
27
+ clsctx: Optional[int] = None,
28
+ pServerInfo: Optional[COSERVERINFO] = None,
29
+ interface: None = None,
30
+ ) -> hints.IClassFactory: ...
31
+ @overload
32
+ def GetClassObject(
33
+ progid: _UnionT[str, Type[CoClass], GUID],
34
+ clsctx: Optional[int] = None,
35
+ pServerInfo: Optional[COSERVERINFO] = None,
36
+ interface: Type[_T_IUnknown] = hints.IClassFactory,
37
+ ) -> _T_IUnknown: ...
38
+
39
+
40
+ def GetClassObject(progid, clsctx=None, pServerInfo=None, interface=None):
41
+ # type: (_UnionT[str, Type[CoClass], GUID], Optional[int], Optional[COSERVERINFO], Optional[Type[IUnknown]]) -> IUnknown
42
+ """Create and return the class factory for a COM object.
43
+
44
+ 'clsctx' specifies how to create the object, use the CLSCTX_... constants.
45
+ 'pServerInfo', if used, must be a pointer to a comtypes.COSERVERINFO instance
46
+ 'interface' may be used to request an interface other than IClassFactory
47
+ """
48
+ clsid = GUID.from_progid(progid)
49
+ return comtypes.CoGetClassObject(clsid, clsctx, pServerInfo, interface)
50
+
51
+
52
+ @overload
53
+ def CreateObject(progid: _UnionT[str, Type[CoClass], GUID]) -> Any: ...
54
+ @overload
55
+ def CreateObject(
56
+ progid: _UnionT[str, Type[CoClass], GUID],
57
+ clsctx: Optional[int] = None,
58
+ machine: Optional[str] = None,
59
+ interface: Optional[Type[_T_IUnknown]] = None,
60
+ dynamic: bool = ...,
61
+ pServerInfo: Optional[COSERVERINFO] = None,
62
+ ) -> _T_IUnknown: ...
63
+ def CreateObject(
64
+ progid: _UnionT[str, Type[CoClass], GUID], # which object to create
65
+ clsctx: Optional[int] = None, # how to create the object
66
+ machine: Optional[str] = None, # where to create the object
67
+ interface: Optional[Type[IUnknown]] = None, # the interface we want
68
+ dynamic: bool = False, # use dynamic dispatch
69
+ pServerInfo: Optional[COSERVERINFO] = None, # server info struct for remoting
70
+ ) -> Any:
71
+ """Create a COM object from 'progid', and try to QueryInterface()
72
+ it to the most useful interface, generating typelib support on
73
+ demand. A pointer to this interface is returned.
74
+
75
+ 'progid' may be a string like "InternetExplorer.Application",
76
+ a string specifying a clsid, a GUID instance, or an object with
77
+ a _clsid_ attribute which should be any of the above.
78
+ 'clsctx' specifies how to create the object, use the CLSCTX_... constants.
79
+ 'machine' allows to specify a remote machine to create the object on.
80
+ 'interface' allows to force a certain interface
81
+ 'dynamic=True' will return a dynamic dispatch object
82
+ 'pServerInfo', if used, must be a pointer to a comtypes.COSERVERINFO instance
83
+ This supercedes 'machine'.
84
+
85
+ You can also later request to receive events with GetEvents().
86
+ """
87
+ clsid = GUID.from_progid(progid)
88
+ logger.debug("%s -> %s", progid, clsid)
89
+ if dynamic:
90
+ if interface:
91
+ raise ValueError("interface and dynamic are mutually exclusive")
92
+ interface = automation.IDispatch
93
+ elif interface is None:
94
+ interface = getattr(progid, "_com_interfaces_", [None])[0]
95
+ if machine is None and pServerInfo is None:
96
+ logger.debug(
97
+ "CoCreateInstance(%s, clsctx=%s, interface=%s)", clsid, clsctx, interface
98
+ )
99
+ obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface)
100
+ else:
101
+ logger.debug(
102
+ "CoCreateInstanceEx(%s, clsctx=%s, interface=%s, machine=%s,\
103
+ pServerInfo=%s)",
104
+ clsid,
105
+ clsctx,
106
+ interface,
107
+ machine,
108
+ pServerInfo,
109
+ )
110
+ if machine is not None and pServerInfo is not None:
111
+ msg = "You cannot set both the machine name and server info."
112
+ raise ValueError(msg)
113
+ obj = comtypes.CoCreateInstanceEx(
114
+ clsid,
115
+ clsctx=clsctx,
116
+ interface=interface,
117
+ machine=machine,
118
+ pServerInfo=pServerInfo,
119
+ )
120
+ if dynamic:
121
+ return comtypes.client.dynamic.Dispatch(obj)
122
+ return _manage(obj, clsid, interface=interface)
123
+
124
+
125
+ @overload
126
+ def CoGetObject(displayname: str, interface: Type[_T_IUnknown]) -> _T_IUnknown: ...
127
+ @overload
128
+ def CoGetObject(
129
+ displayname: str, interface: None = None, dynamic: bool = False
130
+ ) -> Any: ...
131
+ def CoGetObject(
132
+ displayname: str,
133
+ interface: Optional[Type[IUnknown]] = None,
134
+ dynamic: bool = False,
135
+ ) -> Any:
136
+ """Create an object by calling CoGetObject(displayname).
137
+
138
+ Additional parameters have the same meaning as in CreateObject().
139
+ """
140
+ if dynamic:
141
+ if interface is not None:
142
+ raise ValueError("interface and dynamic are mutually exclusive")
143
+ interface = automation.IDispatch
144
+ punk = comtypes.CoGetObject(displayname, interface)
145
+ if dynamic:
146
+ return comtypes.client.dynamic.Dispatch(punk)
147
+ return _manage(punk, clsid=None, interface=interface)
@@ -1,16 +1,63 @@
1
1
  import ctypes
2
+ import logging
2
3
  import traceback
4
+ from ctypes import HRESULT, POINTER, WINFUNCTYPE, OleDLL, Structure, WinDLL
5
+ from ctypes.wintypes import (
6
+ BOOL,
7
+ DWORD,
8
+ HANDLE,
9
+ LPCSTR,
10
+ LPDWORD,
11
+ LPHANDLE,
12
+ LPVOID,
13
+ ULONG,
14
+ )
15
+
3
16
  import comtypes
4
- import comtypes.hresult
5
17
  import comtypes.automation
6
- import comtypes.typeinfo
7
18
  import comtypes.connectionpoints
19
+ import comtypes.hresult
20
+ import comtypes.typeinfo
8
21
  from comtypes.client._generate import GetModule
9
- import logging
10
22
 
11
23
  logger = logging.getLogger(__name__)
12
24
 
13
25
 
26
+ class SECURITY_ATTRIBUTES(Structure):
27
+ _fields_ = [
28
+ ("nLength", DWORD),
29
+ ("lpSecurityDescriptor", LPVOID),
30
+ ("bInheritHandle", BOOL),
31
+ ]
32
+
33
+
34
+ _ole32 = OleDLL("ole32")
35
+
36
+ _CoWaitForMultipleHandles = _ole32.CoWaitForMultipleHandles
37
+ _CoWaitForMultipleHandles.argtypes = [DWORD, DWORD, ULONG, LPHANDLE, LPDWORD]
38
+ _CoWaitForMultipleHandles.restype = HRESULT
39
+
40
+
41
+ _kernel32 = WinDLL("kernel32")
42
+
43
+ _CreateEventA = _kernel32.CreateEventA
44
+ _CreateEventA.argtypes = [POINTER(SECURITY_ATTRIBUTES), BOOL, BOOL, LPCSTR]
45
+ _CreateEventA.restype = HANDLE
46
+
47
+ _SetEvent = _kernel32.SetEvent
48
+ _SetEvent.argtypes = [HANDLE]
49
+ _SetEvent.restype = BOOL
50
+
51
+ PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD)
52
+ _SetConsoleCtrlHandler = _kernel32.SetConsoleCtrlHandler
53
+ _SetConsoleCtrlHandler.argtypes = [PHANDLER_ROUTINE, BOOL]
54
+ _SetConsoleCtrlHandler.restype = BOOL
55
+
56
+ _CloseHandle = _kernel32.CloseHandle
57
+ _CloseHandle.argtypes = [HANDLE]
58
+ _CloseHandle.restype = BOOL
59
+
60
+
14
61
  class _AdviseConnection(object):
15
62
  def __init__(self, source, interface, receiver):
16
63
  self.cp = None
@@ -227,7 +274,7 @@ class EventDumper(object):
227
274
  def handler(self, this, *args, **kw):
228
275
  # XXX handler is called with 'this'. Should we really print "None" instead?
229
276
  args = (None,) + args
230
- print("Event %s(%s)" % (name, ", ".join([repr(a) for a in args])))
277
+ print(f"Event {name}({', '.join([repr(a) for a in args])})")
231
278
 
232
279
  return comtypes.instancemethod(handler, self, EventDumper)
233
280
 
@@ -274,24 +321,22 @@ def PumpEvents(timeout):
274
321
  # CoWaitForMultipleHandles calls the Win32 function
275
322
  # MsgWaitForMultipleObjects.
276
323
 
277
- hevt = ctypes.windll.kernel32.CreateEventA(None, True, False, None)
324
+ hevt = _CreateEventA(None, True, False, None)
278
325
  handles = _handles_type(hevt)
279
326
  RPC_S_CALLPENDING = -2147417835
280
327
 
281
- # @ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint)
328
+ # @ctypes.WINFUNCTYPE(BOOL, DWORD)
282
329
  def HandlerRoutine(dwCtrlType):
283
330
  if dwCtrlType == 0: # CTRL+C
284
- ctypes.windll.kernel32.SetEvent(hevt)
331
+ _SetEvent(hevt)
285
332
  return 1
286
333
  return 0
287
334
 
288
- HandlerRoutine = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint)(HandlerRoutine)
289
-
290
- ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 1)
335
+ _SetConsoleCtrlHandler(PHANDLER_ROUTINE(HandlerRoutine), 1)
291
336
 
292
337
  try:
293
338
  try:
294
- res = ctypes.oledll.ole32.CoWaitForMultipleHandles(
339
+ res = _CoWaitForMultipleHandles(
295
340
  0,
296
341
  int(timeout * 1000),
297
342
  len(handles),
@@ -304,5 +349,5 @@ def PumpEvents(timeout):
304
349
  else:
305
350
  raise KeyboardInterrupt
306
351
  finally:
307
- ctypes.windll.kernel32.CloseHandle(hevt)
308
- ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 0)
352
+ _CloseHandle(hevt)
353
+ _SetConsoleCtrlHandler(PHANDLER_ROUTINE(HandlerRoutine), 0)
@@ -5,14 +5,14 @@ import logging
5
5
  import os
6
6
  import sys
7
7
  import types
8
- from typing import Any, Tuple, List, Mapping, Optional, Dict, Union as _UnionT
9
8
  import winreg
9
+ from typing import Any, Dict, List, Mapping, Optional, Tuple
10
+ from typing import Union as _UnionT
10
11
 
11
- from comtypes import GUID, typeinfo
12
12
  import comtypes.client
13
+ from comtypes import GUID, typeinfo
13
14
  from comtypes.tools import codegenerator, tlbparser
14
15
 
15
-
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
18
  PATH = os.environ["PATH"].split(os.pathsep)
@@ -139,20 +139,16 @@ def _load_tlib(obj: Any) -> typeinfo.ITypeLib:
139
139
  elif isinstance(obj, GUID):
140
140
  clsid = str(obj)
141
141
  # lookup associated typelib in registry
142
- with winreg.OpenKey(
143
- winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\TypeLib" % clsid
144
- ) as key:
142
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"CLSID\{clsid}\TypeLib") as key:
145
143
  libid = winreg.EnumValue(key, 0)[1]
146
- with winreg.OpenKey(
147
- winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\Version" % clsid
148
- ) as key:
144
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"CLSID\{clsid}\Version") as key:
149
145
  ver = winreg.EnumValue(key, 0)[1].split(".")
150
146
  return typeinfo.LoadRegTypeLib(GUID(libid), int(ver[0]), int(ver[1]), 0)
151
147
  # obj is a sequence containing libid
152
148
  elif isinstance(obj, (tuple, list)):
153
149
  libid, ver = obj[0], obj[1:]
154
150
  if not ver: # case of version numbers are not containing
155
- with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r"TypeLib\%s" % libid) as key:
151
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"TypeLib\{libid}") as key:
156
152
  ver = [int(v, base=16) for v in winreg.EnumKey(key, 0).split(".")]
157
153
  return typeinfo.LoadRegTypeLib(GUID(libid), *ver)
158
154
  # obj is a COMObject implementation
@@ -161,7 +157,7 @@ def _load_tlib(obj: Any) -> typeinfo.ITypeLib:
161
157
  # obj is a pointer of ITypeLib
162
158
  elif isinstance(obj, ctypes.POINTER(typeinfo.ITypeLib)):
163
159
  return obj # type: ignore
164
- raise TypeError("'%r' is not supported type for loading typelib" % obj)
160
+ raise TypeError(f"'{obj!r}' is not supported type for loading typelib")
165
161
 
166
162
 
167
163
  def _get_existing_module(tlib: typeinfo.ITypeLib) -> Optional[types.ModuleType]:
@@ -0,0 +1,114 @@
1
+ import logging
2
+ from _ctypes import COMError
3
+ from typing import Any, Optional, Type
4
+
5
+ import comtypes
6
+ import comtypes.client.dynamic
7
+ from comtypes import GUID, IUnknown, automation, typeinfo
8
+ from comtypes.client._generate import GetModule
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ def wrap_outparam(punk: Any) -> Any:
14
+ logger.debug("wrap_outparam(%s)", punk)
15
+ if not punk:
16
+ return None
17
+ if punk.__com_interface__ == automation.IDispatch:
18
+ return GetBestInterface(punk)
19
+ return punk
20
+
21
+
22
+ def GetBestInterface(punk: Any) -> Any:
23
+ """Try to QueryInterface a COM pointer to the 'most useful'
24
+ interface.
25
+
26
+ Get type information for the provided object, either via
27
+ IDispatch.GetTypeInfo(), or via IProvideClassInfo.GetClassInfo().
28
+ Generate a wrapper module for the typelib, and QI for the
29
+ interface found.
30
+ """
31
+ if not punk: # NULL COM pointer
32
+ return punk # or should we return None?
33
+ # find the typelib and the interface name
34
+ logger.debug("GetBestInterface(%s)", punk)
35
+ try:
36
+ try:
37
+ pci = punk.QueryInterface(typeinfo.IProvideClassInfo)
38
+ logger.debug("Does implement IProvideClassInfo")
39
+ except COMError:
40
+ # Some COM objects support IProvideClassInfo2, but not IProvideClassInfo.
41
+ # These objects are broken, but we support them anyway.
42
+ logger.debug(
43
+ "Does NOT implement IProvideClassInfo, trying IProvideClassInfo2"
44
+ )
45
+ pci = punk.QueryInterface(typeinfo.IProvideClassInfo2)
46
+ logger.debug("Does implement IProvideClassInfo2")
47
+ tinfo = pci.GetClassInfo() # TypeInfo for the CoClass
48
+ # find the interface marked as default
49
+ ta = tinfo.GetTypeAttr()
50
+ for index in range(ta.cImplTypes):
51
+ if tinfo.GetImplTypeFlags(index) == 1:
52
+ break
53
+ else:
54
+ if ta.cImplTypes != 1:
55
+ # Hm, should we use dynamic now?
56
+ raise TypeError("No default interface found")
57
+ # Only one interface implemented, use that (even if
58
+ # not marked as default).
59
+ index = 0
60
+ href = tinfo.GetRefTypeOfImplType(index)
61
+ tinfo = tinfo.GetRefTypeInfo(href)
62
+ except COMError:
63
+ logger.debug("Does NOT implement IProvideClassInfo/IProvideClassInfo2")
64
+ try:
65
+ pdisp = punk.QueryInterface(automation.IDispatch)
66
+ except COMError:
67
+ logger.debug("No Dispatch interface: %s", punk)
68
+ return punk
69
+ try:
70
+ tinfo = pdisp.GetTypeInfo(0)
71
+ except COMError:
72
+ pdisp = comtypes.client.dynamic.Dispatch(pdisp)
73
+ logger.debug("IDispatch.GetTypeInfo(0) failed: %s" % pdisp)
74
+ return pdisp
75
+ typeattr = tinfo.GetTypeAttr()
76
+ logger.debug("Default interface is %s", typeattr.guid)
77
+ try:
78
+ punk.QueryInterface(IUnknown, typeattr.guid)
79
+ except COMError:
80
+ logger.debug("Does not implement default interface, returning dynamic object")
81
+ return comtypes.client.dynamic.Dispatch(punk)
82
+
83
+ itf_name = tinfo.GetDocumentation(-1)[0] # interface name
84
+ tlib = tinfo.GetContainingTypeLib()[0] # typelib
85
+
86
+ # import the wrapper, generating it on demand
87
+ mod = GetModule(tlib)
88
+ # Python interface class
89
+ interface = getattr(mod, itf_name)
90
+ logger.debug("Implements default interface from typeinfo %s", interface)
91
+ # QI for this interface
92
+ # XXX
93
+ # What to do if this fails?
94
+ # In the following example the engine.Eval() call returns
95
+ # such an object.
96
+ #
97
+ # engine = CreateObject("MsScriptControl.ScriptControl")
98
+ # engine.Language = "JScript"
99
+ # engine.Eval("[1, 2, 3]")
100
+ #
101
+ # Could the above code, as an optimization, check that QI works,
102
+ # *before* generating the wrapper module?
103
+ result = punk.QueryInterface(interface)
104
+ logger.debug("Final result is %s", result)
105
+ return result
106
+
107
+
108
+ def _manage(
109
+ obj: Any, clsid: Optional[GUID], interface: Optional[Type[IUnknown]]
110
+ ) -> Any:
111
+ obj.__dict__["__clsid"] = str(clsid)
112
+ if interface is None:
113
+ obj = GetBestInterface(obj)
114
+ return obj
@@ -1,10 +1,9 @@
1
1
  import ctypes
2
2
  from typing import Any, Dict, Optional, Set, Type, TypeVar
3
3
 
4
- from comtypes import automation
4
+ from comtypes import GUID, COMError, IUnknown, _is_object, automation
5
+ from comtypes import hresult as hres
5
6
  from comtypes.client import lazybind
6
- from comtypes import COMError, GUID, IUnknown, hresult as hres, _is_object
7
-
8
7
 
9
8
  _T_IUnknown = TypeVar("_T_IUnknown", bound=IUnknown)
10
9
  # These errors generally mean the property or method exists,
@@ -1,16 +1,15 @@
1
1
  import comtypes
2
2
  import comtypes.automation
3
-
4
- from comtypes.automation import IEnumVARIANT
5
- from comtypes.automation import DISPATCH_METHOD
6
- from comtypes.automation import DISPATCH_PROPERTYGET
7
- from comtypes.automation import DISPATCH_PROPERTYPUT
8
- from comtypes.automation import DISPATCH_PROPERTYPUTREF
9
-
10
- from comtypes.automation import DISPID_VALUE
11
- from comtypes.automation import DISPID_NEWENUM
12
-
13
- from comtypes.typeinfo import FUNC_PUREVIRTUAL, FUNC_DISPATCH
3
+ from comtypes.automation import (
4
+ DISPATCH_METHOD,
5
+ DISPATCH_PROPERTYGET,
6
+ DISPATCH_PROPERTYPUT,
7
+ DISPATCH_PROPERTYPUTREF,
8
+ DISPID_NEWENUM,
9
+ DISPID_VALUE,
10
+ IEnumVARIANT,
11
+ )
12
+ from comtypes.typeinfo import FUNC_DISPATCH, FUNC_PUREVIRTUAL
14
13
 
15
14
 
16
15
  class FuncDesc(object):
@@ -67,7 +66,7 @@ class NamedProperty(object):
67
66
 
68
67
  def __iter__(self):
69
68
  """Explicitly disallow iteration."""
70
- msg = "%r is not iterable" % self.disp
69
+ msg = f"{self.disp!r} is not iterable"
71
70
  raise TypeError(msg)
72
71
 
73
72
 
@@ -151,7 +150,7 @@ class Dispatch(object):
151
150
  if descr.cParams == 1:
152
151
  return self._comobj._invoke(descr.memid, descr.invkind, 0)
153
152
  else:
154
- raise RuntimeError("funckind %d not yet implemented" % descr.funckind)
153
+ raise RuntimeError(f"funckind {descr.funckind:d} not yet implemented")
155
154
  put = self.__bind(name, DISPATCH_PROPERTYPUT)
156
155
  putref = self.__bind(name, DISPATCH_PROPERTYPUTREF)
157
156
  return NamedProperty(self, descr, put, putref)
@@ -1,6 +1,7 @@
1
1
  import sys
2
2
  from ctypes import *
3
- from comtypes import IUnknown, COMMETHOD, GUID, HRESULT, dispid
3
+
4
+ from comtypes import COMMETHOD, GUID, HRESULT, IUnknown, dispid
4
5
 
5
6
  _GUID = GUID
6
7