#605 EnsureDispatch error 2147352567 but not Dispatch

closed-works-for-me
nobody
com (105)
5
2012-08-09
2012-08-07
Anonymous
No

I've got a strange problem :

I'e trying to export Outlook Contacts in a List of Dictionnary. My code works perfectly with win32com.client.Dispatch("Outlook.Application). But it returns 0 contacts with win32com.client.gencache.EnsureDispatch("Outlook.Application) that is supposed to be faster and "safer". Here's my code :

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))

So when i replace :

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

With :

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

It returns this errors :

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)

The message means "Matrix index out of bounds". The strangiest thing is that after I called EnsureDispatch, win32com.client.Dispatch doesn't works anymore. I have to uninstall pywin32 and reinstall it...

I'm running with Python2.7.3 32-bit with Outlook 2003 32-bit

Thanks

Discussion

  • Roger Upole
    Roger Upole
    2012-08-07

    It appears outlook is using a 1-based index for the contact items.
    When using the generated wrapper classes, iteration is performed by
    calling for Items starting with 0, and throws the error you're seeing.

    The dynamic Dispatch is querying for an iterator using DISPID_NEWENUM,
    and the resulting enumerator works regardless of the indexing scheme.
    The makepy generated classes should probably use that same process.

    As a workaround, you can use win32com.client.dynamic.DumbDispatch to
    get the dynamic behaviour for just the mapiContacts object.
    You can remove the makepy support by simply clearing the \win32com\gen_py directory rather than reinstalling.

     
  • Mark Hammond
    Mark Hammond
    2012-08-07

    FWIW, EnsureDispatch will generated code into the win32com\client\gen_py directory (or possibly in %temp%\gen_py) - removing that directory should avoid needing to reinstall pywin32 to reset the behaviour.

    As to the problem itself, can you check if "self.mapiContacts.Items(0)" throws an exception? I'm wondering if the code is looping, but isn't handling the exception to stop the looping correctly (ie, I'm wondering if the code is failing *after* it successfully enumerates the contacts or before).

     
  • Mark Hammond
    Mark Hammond
    2012-08-07

    oops - I wrote that before seeing Roger's reply...

     

  • Anonymous
    2012-08-08

    Thx for fast answer !

    you're both right, outlook is using a 1-base index. If i try this simple code :

    import win32com.client
    olApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")
    namespace = olApp.GetNamespace(u"MAPI")
    # olFolderContacts = 10 :
    mapiContacts = namespace.GetDefaultFolder(10).Items
    print mapiContacts[0] # INDEX 0 CRASHES

    It crashes with the same error. But if i try with index 1, 2, 3 etc. it works !

    My code works with win32com.client.dynamic.DumbDispatch. What's the cons of DumbDispatch ?

     
  • Mark Hammond
    Mark Hammond
    2012-08-08

    So it looks like we need to work out why _NewEnum isn't being used in that case, as Roger mentioned.

    DumpDispatch is just like regular Dispatch when EnsureDispatch hasn't been used. IOW, DumbDispatch will always ignore the magic done by EnsureDispatch.

     
  • Roger Upole
    Roger Upole
    2012-08-08

    I took a closer look at this, and the makepy code is checking for the NewEnum method, but it doesn't appear in the TypeInfo. I think the right thing to do would be to always try to Invoke DISPID_NEWENUM first, and fall back to iterating Items if that fails.

     
  • Mark Hammond
    Mark Hammond
    2012-08-08

    Sounds good to me!

     

  • Anonymous
    2012-08-08

    So it will be corrected in a future version ?

    As a workaround, i use :

    for i in range (1, len(self.mapiContacts)+1):
    contact = self.mapiContacts[i]

    Thx 4 everything !

     

  • Anonymous
    2012-08-08

    Allow get started with cocktail attire for graduation. These attire are most common formal attire for that functions. If this entails graduation occasion, it amid the new preferred suits for that young women of all ages. No matter if you buy on the net or check out a close-by boutique, you will discover best dresses in cream, beige and whitened shades. Since whitened shade provides a sexy turn towards the gown, the style of graduation dresses is obvious much more appropriately.
    http://forums.massassi.net/vb3/member.php?87733-carpinteyrolwr

     
    Last edit: Anonymous 2014-10-28
  • Mark Hammond
    Mark Hammond
    2012-08-08

    I don't know the outlook object model well enough to say - you might like to try mailing the python-win32 mailing list to see what others are doing.

     

  • Anonymous
    2012-08-09

    Found it !

    EnsureDispatch is way faster and "framed" !

    All the properties must be spelled exactly as the MSDN doc. i.e. with a MAJ at the beginning :

    contact.ItemPrperties works but not contact.itemProperties

    (with normal dispatch, it's not case sensitive)

    Thx again !

     

  • Anonymous
    2012-08-09

    • status: open --> closed-works-for-me
     
  • Roger Upole
    Roger Upole
    2012-08-19

    Makepy generated classes now check for an enumerator at runtime, so in the future you shouldn't need to use dynamic in these cases.