#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...

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    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!

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    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 !

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    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.

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    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 !

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    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.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks