简体   繁体   English

Python - 获取 win32com 类的所有属性/属性的列表

[英]Python - Get list of all attributes/properties of a win32com class

I am a newbie in Python.我是 Python 的新手。 I have to extract emails from Outlook and get all attributes/properties of the emails.我必须从 Outlook 中提取电子邮件并获取电子邮件的所有属性。

Retrieving properties one by one, for the attributes/properties that I know they exist works fine (.Subject, .Body, etc.).一一检索属性,对于我知道它们存在的属性/属性工作正常(.Subject、.Body 等)。

But, I need to get all possible attributes.但是,我需要获得所有可能的属性。 That's where my problem is.这就是我的问题所在。 I have been looking for hours, the only answers I found were using:我一直在寻找几个小时,我找到的唯一答案是使用:

  • vars()变量()
  • dir()目录()
  • inspect.getmembers(obj)检查.getmembers(对象)
  • __dict__
  • etc.等等。
Which does not give me the list of properties like: 这没有给我属性列表,例如:

  • .Subject 。主题
  • .Body 。身体
  • .SentOn 。在发送
  • etc.等等。
Could someone help ? 有人可以帮忙吗?

Here is the extract of my test Notebook :这是我的测试笔记本的摘录:

 ####### Retrieve email from Outlook ####### import win32com.client objOutlookMAPI=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")​ ​### Define folder objOlFolder = objOutlookMAPI.GetDefaultFolder(6) ​### Retrieve ant print email objOlMessages = objOlFolder.Items​ # objMessage : class 'win32com.client.CDispatch' objMessage = objOlMessages.GetLast() print(objMessage.Subject) > Are you going to Las Vegas for Black Hat, DefCon, Bsides, or Hacking Diversity? Either or join us on our adventures! vars(objMessage) > {'_builtMethods_': {}, '_enum_': None, '_lazydata_': (<PyITypeInfo at 0x0000021EC7B7D170 with obj at 0x0000021EC7B4B2F8>, <PyITypeComp at 0x0000021EC7B7D620 with obj at 0x0000021EC7B4B058>), '_mapCachedItems_': {}, '_oleobj_': <PyIDispatch at 0x0000021EC7B7D290 with obj at 0x0000021EC7B4AAA8>, '_olerepr_': <win32com.client.build.LazyDispatchItem at 0x21ec8a7ba90>, '_unicode_to_string_': None, '_username_': 'GetLast'} dir(objMessage) #import inspect #inspect.getmembers(objMessage) > [`'_ApplyTypes_'`, `'_FlagAsMethod'`, `'_LazyAddAttr_'`, `'_NewEnum'`, `'_Release_'`, `'__AttrToID__'`, `'__LazyMap__'`, `'__bool__'`, `'__call__'`, `'__class__'`, `'__delattr__'`, `'__dict__'`, `'__dir__'`, `'__doc__'`, `'__eq__'`, `'__format__'`, `'__ge__'`, `'__getattr__'`, `'__getattribute__'`, `'__getitem__'`, `'__gt__'`, `'__hash__'`, `'__init__'`, `'__init_subclass__'`, `'__int__'`, `'__le__'`, `'__len__'`, `'__lt__'`, `'__module__'`, `'__ne__'`, `'__new__'`, `'__reduce__'`, `'__reduce_ex__'`, `'__repr__'`, `'__setattr__'`, `'__setitem__'`, `'__sizeof__'`, `'__str__'`, `'__subclasshook__'`, `'__weakref__'`, `'_builtMethods_'`, `'_enum_'`, `'_find_dispatch_type_'`, `'_get_good_object_'`, `'_get_good_single_object_'`, `'_lazydata_'`, `'_make_method_'`, `'_mapCachedItems_'`, `'_oleobj_'`, `'_olerepr_'`, `'_print_details_'`, `'_proc_'`, `'_unicode_to_string_'`, `'_username_'`, `'_wrap_dispatch_'`] ####### Retrieve email from Outlook ####### import win32com.client objOutlookMAPI=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")​ ​### Define folder objOlFolder = objOutlookMAPI.GetDefaultFolder(6) ​### Retrieve ant print email objOlMessages = objOlFolder.Items​ # objMessage : class 'win32com.client.CDispatch' objMessage = objOlMessages.GetLast() print(objMessage.Subject) > Are you going to Las Vegas for Black Hat, DefCon, Bsides, or Hacking Diversity? Either or join us on our adventures! vars(objMessage) > {'_builtMethods_': {}, '_enum_': None, '_lazydata_': (<PyITypeInfo at 0x0000021EC7B7D170 with obj at 0x0000021EC7B4B2F8>, <PyITypeComp at 0x0000021EC7B7D620 with obj at 0x0000021EC7B4B058>), '_mapCachedItems_': {}, '_oleobj_': <PyIDispatch at 0x0000021EC7B7D290 with obj at 0x0000021EC7B4AAA8>, '_olerepr_': <win32com.client.build.LazyDispatchItem at 0x21ec8a7ba90>, '_unicode_to_string_': None, '_username_': 'GetLast'} dir(objMessage) #import inspect #inspect.getmembers(objMessage) > [`'_ApplyTypes_'`, `'_FlagAsMethod'`, `'_LazyAddAttr_'`, `'_NewEnum'`, `'_Release_'`, `'__AttrToID__'`, `'__LazyMap__'`, `'__bool__'`, `'__call__'`, `'__class__'`, `'__delattr__'`, `'__dict__'`, `'__dir__'`, `'__doc__'`, `'__eq__'`, `'__format__'`, `'__ge__'`, `'__getattr__'`, `'__getattribute__'`, `'__getitem__'`, `'__gt__'`, `'__hash__'`, `'__init__'`, `'__init_subclass__'`, `'__int__'`, `'__le__'`, `'__len__'`, `'__lt__'`, `'__module__'`, `'__ne__'`, `'__new__'`, `'__reduce__'`, `'__reduce_ex__'`, `'__repr__'`, `'__setattr__'`, `'__setitem__'`, `'__sizeof__'`, `'__str__'`, `'__subclasshook__'`, `'__weakref__'`, `'_builtMethods_'`, `'_enum_'`, `'_find_dispatch_type_'`, `'_get_good_object_'`, `'_get_good_single_object_'`, `'_lazydata_'`, `'_make_method_'`, `'_mapCachedItems_'`, `'_oleobj_'`, `'_olerepr_'`, `'_print_details_'`, `'_proc_'`, `'_unicode_to_string_'`, `'_username_'`, `'_wrap_dispatch_'`] ####### Retrieve email from Outlook ####### import win32com.client objOutlookMAPI=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")​ ​### Define folder objOlFolder = objOutlookMAPI.GetDefaultFolder(6) ​### Retrieve ant print email objOlMessages = objOlFolder.Items​ # objMessage : class 'win32com.client.CDispatch' objMessage = objOlMessages.GetLast() print(objMessage.Subject) > Are you going to Las Vegas for Black Hat, DefCon, Bsides, or Hacking Diversity? Either or join us on our adventures! vars(objMessage) > {'_builtMethods_': {}, '_enum_': None, '_lazydata_': (<PyITypeInfo at 0x0000021EC7B7D170 with obj at 0x0000021EC7B4B2F8>, <PyITypeComp at 0x0000021EC7B7D620 with obj at 0x0000021EC7B4B058>), '_mapCachedItems_': {}, '_oleobj_': <PyIDispatch at 0x0000021EC7B7D290 with obj at 0x0000021EC7B4AAA8>, '_olerepr_': <win32com.client.build.LazyDispatchItem at 0x21ec8a7ba90>, '_unicode_to_string_': None, '_username_': 'GetLast'} dir(objMessage) #import inspect #inspect.getmembers(objMessage) > [`'_ApplyTypes_'`, `'_FlagAsMethod'`, `'_LazyAddAttr_'`, `'_NewEnum'`, `'_Release_'`, `'__AttrToID__'`, `'__LazyMap__'`, `'__bool__'`, `'__call__'`, `'__class__'`, `'__delattr__'`, `'__dict__'`, `'__dir__'`, `'__doc__'`, `'__eq__'`, `'__format__'`, `'__ge__'`, `'__getattr__'`, `'__getattribute__'`, `'__getitem__'`, `'__gt__'`, `'__hash__'`, `'__init__'`, `'__init_subclass__'`, `'__int__'`, `'__le__'`, `'__len__'`, `'__lt__'`, `'__module__'`, `'__ne__'`, `'__new__'`, `'__reduce__'`, `'__reduce_ex__'`, `'__repr__'`, `'__setattr__'`, `'__setitem__'`, `'__sizeof__'`, `'__str__'`, `'__subclasshook__'`, `'__weakref__'`, `'_builtMethods_'`, `'_enum_'`, `'_find_dispatch_type_'`, `'_get_good_object_'`, `'_get_good_single_object_'`, `'_lazydata_'`, `'_make_method_'`, `'_mapCachedItems_'`, `'_oleobj_'`, `'_olerepr_'`, `'_print_details_'`, `'_proc_'`, `'_unicode_to_string_'`, `'_username_'`, `'_wrap_dispatch_'`]

For posterity here, I found what I needed in the AppointmentItem object on this page:对于这里的后代,我在此页面上的 AppointmentItem 对象中找到了我需要的内容:

Outlook Visual Basic for Applications (VBA) reference Outlook Visual Basic for Applications (VBA) 参考

Just expand that object on the left side of the page, and then expand properties.只需在页面左侧展开该对象,然后展开属性即可。 Found everything I needed there.在那里找到了我需要的一切。 Also a MeetingItem object, still in the process of figuring out the difference (which sounds like it's obvious, but a lot of the appointments I'm getting back are actually meetings (ie have attendees).也是一个 MeetingItem 对象,仍在找出差异的过程中(这听起来很明显,但我回来的很多约会实际上是会议(即有与会者)。

I found a way to do it, actually:我找到了一种方法,实际上:

The plan is to create a macro in a second presentation that you call from within python and that is, with the help of tlbinf32.dll, able to get all members of an object.计划是在您从 python 中调用的第二个演示文稿中创建一个宏,也就是说,在 tlbinf32.dll 的帮助下,能够获取对象的所有成员。

The Second Presentation第二场演讲

  1. To start, you want to download the tlbinf32.dll .首先,您要下载tlbinf32.dll
    FOR 64-bit SYSTEMS: Follow this guide to properly set up the 32-bit-DLL!对于64 位系统:按照指南正确设置 32 位 DLL! I also had problems with the HP Print Scan Doctor Service : I needed to disable that service and uninstall HP Smart .我也遇到了HP Print Scan Doctor Service :我需要禁用该服务并卸载HP Smart (and reboot) (并重新启动)
  2. Create a new .pptm file (pptx with macros) and open it (I named it GetMembersUtil.pptm )创建一个新的.pptm文件(带有宏的 pptx)并打开它(我将其命名为GetMembersUtil.pptm
  3. In that presentation, create a new macro (the name is irrelevant) and edit it (View->Macros)在该演示文稿中,创建一个新宏(名称无关紧要)并对其进行编辑(查看->宏)
  4. Add a reference to your tlbinf32.dll that you just downloaded (Tools->References)添加对刚刚下载的tlbinf32.dll的引用(工具-> 引用)
  5. Paste the following function after the macro在宏后粘贴以下函数
Function GetMembers(obj)
    ' Declare vars
    Dim TLI
    Dim TypeInfo
    Dim Members
    
    ' Create new ArrayList since we don't know how many Members obj has
    Set Members = CreateObject("System.Collections.ArrayList")
    
    ' Initialize tlbinf
    Set TLI = CreateObject("TLI.TLIApplication")
    Set TypeInfo = TLI.InterfaceInfoFromObject(obj)
    
    ' iterate over each Member
    For Each MemberInfo In TypeInfo.Members
        Members.Add MemberInfo.Name
    Next
    
    ' Convert ArrayList back to native vba Array because you can't return an ArrayList
    GetMembers = Members.ToArray()
    
End Function

this function takes an object as input and returns all the members of that object此函数将一个对象作为输入并返回该对象的所有成员

  1. Save your presentation in the local directory of your python file将演示文稿保存在 python 文件的本地目录中

The Python Side Python 方面

To be able to use the macro we need to make sure that the presentation we just created is openend为了能够使用宏,我们需要确保我们刚刚创建的演示文稿是 openend

def vba_get_members(app: win32com.client.CDispatch, obj: win32com.client.CDispatch) -> tuple[str, ...]:
    # os.path.abspath is very important
    ensure_opened(app, os.path.abspath("GetMembersUtil.pptm"))
    return app.Run("GetMembersUtil.pptm!GetMembers", obj)

def ensure_opened(app: win32com.client.CDispatch, file_path):
    # check if presentation is already opened
    for presentation in app.Presentations:
        pp_filepath = os.path.join(presentation.Path, presentation.Name)

        if pp_filepath == file_path:
            # presentation already opened
            break
    else:
        # presentation wasn't already opened
        app.Presentations.Open(file_path)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM