win32com.client.Dispatch работает, но не win32com.client.gencache.EnsureDispatch

Я изучаю win32com для python, и у меня странная проблема.

Я пытаюсь экспортировать контакты Outlook в список словаря. Мой код отлично работает с win32com.client.Dispatch ("Outlook.Application). Но он возвращает 0 контактов с win32com.client.gencache.EnsureDispatch (" Outlook.Application), который должен быть быстрее и безопаснее ". Вот мой код:

class MapiImport():
    def __init__(self):
        self.olApp = win32com.client.Dispatch("Outlook.Application")
        self.namespace = self.olApp.GetNamespace(u"MAPI")
        # olFolderContacts = 10 :
        self.mapiContacts = self.namespace.GetDefaultFolder(10).Items

    def getContacts(self, *fields):
        contacts = []
        # Class == 40 is ContactItem
        # Class == 69 is DistListItem
        # Exclude ditribution list and others objects != ContactItem
        for contact in filter(lambda x: x.Class == 40,self.mapiContacts) :
            if not fields :
                ctact = dict((x.Name,x.Value) for x in contact.ItemProperties)
            else :
                ctact = {}
                for field in fields :
                    itemProp = contact.itemProperties[field]
                    ctact[field] = itemProp.Value
            contacts.append(ctact)
        return contacts

#====TEST SCRIPT====
myMAPI = MapiImport()
fields = (u"LastName",u"FirstName",u"Companies",
          u"HomeTelephoneNumber",u"Home2TelephoneNumber",
          u"MobileTelephoneNumber",
          u"BusinessTelephoneNumber",u"Business2TelephoneNumber",
          u"Email1Address",u"Email2Address",u"Email3Address",
          u"HomeAddress",u"BusinessAddress",
          u"Birthday",u"Anniversary",
          u"Body")
print(myMAPI.getContacts(*fields))

Итак, когда я заменяю:

olApp = win32com.client.Dispatch("Outlook.Application")

С участием :

olApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")

Он возвращает следующие ошибки:

Traceback (most recent call last):
  File "D:\Documents and Settings\da7950\Mes documents\Dropbox\cheetahImporter\mapiImport.py", line 42, in <module>
    print(myMAPI.getContacts(*fields))
  File "D:\Documents and Settings\da7950\Mes documents\Dropbox\cheetahImporter\mapiImport.py", line 19, in getContacts
    for contact in filter(lambda x: x.Class == 40,self.mapiContacts) :
  File "D:\Documents and Settings\da7950\Mes documents\Python27\lib\site-packages\win32com\gen_py\00062FFF-0000-0000-C000-000000000046x0x9x2\_Items.py", line 122, in __getitem__
    return self._get_good_object_(self._oleobj_.Invoke(*(81, LCID, 1, 1, item)), "Item")
com_error: (-2147352567, "Une exception s'est produite.", (4096, u'Microsoft Office Outlook', u'Index de la matrice en dehors des limites.', None, 0, -2147352567), None)

Сообщение означает «Матричный индекс выходит за границы». Самое странное, что после того, как я вызвал EnsureDispatch, win32com.client.Dispatch больше не работает. Мне нужно удалить pywin32 и переустановить его ...

Я использую 64-разрядную версию Python2.7.3 с 32-разрядной версией Outlook 2007

Спасибо


person franckgaga    schedule 24.07.2012    source источник
comment
Каковы плюсы и минусы раннего связывания (EnsureDispatch) и позднего связывания (Disaptch)? Можно ли оставить свой код таким (он будет работать на многих платформах)?   -  person franckgaga    schedule 26.07.2012
comment
IMO win32com.client.Dispatch не работает, потому что вы создали кеш в Temp\gen_py папке   -  person Winand    schedule 19.04.2016


Ответы (1)


Я нашел решение. Это ошибка win32com makepy ...

Основная проблема заключается в том, что Outlook индексируется на основе 1 для olContactItem (в отличие от индекса на основе 0 для python)

olApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")           
namespace = olApp.GetNamespace(u"MAPI")           
# olFolderContacts = 10 :           
mapiContacts = namespace.GetDefaultFolder(10).Items
for i in range(1,len(mapiContacts)+1) :
    contact = self.mapiContacts[i]
    ...

Есть еще одна проблема с contact.itemProperties. Все свойства чувствительны к регистру с EnsureDispatch, поэтому:

contact.ItemProperties("FullName").Value
#       ^

работает, но не:

contact.itemProperties("FullName").Value
#       ^

Чтобы получить правильные имена, обратитесь к: эталонной модели Microsoft Outlook ContactItem на MSDN

person franckgaga    schedule 08.08.2012