[python-win32] Adding attachments to extended MAPI messages

Shayan Raghavjee shayanr at sjsoft.com
Tue Sep 28 14:31:49 CEST 2004


Hi,

I'm trying to extend David Fraser & Stephen Emslie's extended MAPI code 
to include attachments, but with not much success. It looks like 
CreateAttachment returns a list with an attachment number and a pyAttach 
object. I've been trying to add the desired properties to the pyAttach 
object using it SetProps method, as it's done in the message itself.

In the end, I get an unnamed attachment, with some of the data I put in, 
except the <cr> character's been changed to something else, (But that 
may be because of the way I'm reading the file perhaps?)  All the other 
properties seem to be ignored, and aren't there if I examine the message 
with something like OutlookSpy.

I've included the test code I'm trying, does anyone have any ideas?

Thanks,
Shayan Raghavjee
St. James Software
-------------- next part --------------
#!/usr/bin/env python

"""module to send mail with Extended MAPI using the pywin32 mapi wrappers..."""

# this was based on Jason Hattingh's C++ code at http://www.codeproject.com/internet/mapadmin.asp
# written by David Fraser <davidf at sjsoft.com> and Stephen Emslie <stephene at sjsoft.com>
# you can test this by changing the variables at the bottom and running from the command line

from win32com.mapi import mapi
from win32com.mapi import mapitags

# Pre 2.2.1 compat.
try: True, False
except NameError: True = 1==1; False = 1==0

def SendEMAPIMail(Subject="", Message="", SendTo=None, SendCC=None, SendBCC=None, MAPIProfile=None):
    """Sends an email to the recipient using the extended MAPI interface
    Subject and Message are strings
    Send{To,CC,BCC} are comma-separated address lists
    MAPIProfile is the name of the MAPI profile"""

    # initialize and log on
    mapi.MAPIInitialize(None)
    session = mapi.MAPILogonEx(0, MAPIProfile, None, mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT)
    messagestorestable = session.GetMsgStoresTable(0)
    messagestorestable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A, mapitags.PR_DEFAULT_STORE),0)

    while (True):
        rows = messagestorestable.QueryRows(1, 0)
        if len(rows) != 1:
            break
        row = rows[0]
        propertyid, propertyvalue = row[0]
        if (propertyid == mapitags.PR_DEFAULT_STORE and propertyvalue == True):
            break

    # unpack the row and open the message store
    (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row
    msgstore = session.OpenMsgStore(0,eid,None,mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS)

    # get the outbox
    hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0)
    (tag, eid) = props[0]
    outboxfolder = msgstore.OpenEntry(eid,None,mapi.MAPI_BEST_ACCESS)

    # create the message and the addrlist
    message = outboxfolder.CreateMessage(None,0)
    # note: you can use the resolveaddress functions for this. but you may get headaches
    pal = []
    def makeentry(recipient, recipienttype):
      return ((mapitags.PR_RECIPIENT_TYPE, recipienttype),
              (mapitags.PR_SEND_RICH_INFO, False),
              (mapitags.PR_DISPLAY_TYPE, 0),
              (mapitags.PR_OBJECT_TYPE, 6),
              (mapitags.PR_EMAIL_ADDRESS_A, recipient),
              (mapitags.PR_ADDRTYPE_A, 'SMTP'),
              (mapitags.PR_DISPLAY_NAME_A, recipient))
    
    if SendTo:
      pal.extend([makeentry(recipient, mapi.MAPI_TO) for recipient in SendTo.split(",")])
    if SendCC:
      pal.extend([makeentry(recipient, mapi.MAPI_CC) for recipient in SendCC.split(",")])
    if SendBCC:
      pal.extend([makeentry(recipient, mapi.MAPI_BCC) for recipient in SendBCC.split(",")])

    # add the resolved recipients to the message
    message.ModifyRecipients(mapi.MODRECIP_ADD,pal)

    f = open('c:\\nexsig.gif')

    iAttach = message.CreateAttach(None,0)
    iAttach[1].SetProps([
                         (mapitags.PR_ATTACH_METHOD, mapi.ATTACH_BY_VALUE),
                         (mapitags.PR_ATTACH_LONG_FILENAME, 'test.gif'),
                         (mapitags.PR_ATTACH_FILENAME, 'test.gif'),
                         (mapitags.PR_ATTACH_EXTENSION, '.gif'),
                         (mapitags.PR_ATTACH_NUM, iAttach[0]),
                         (mapitags.PR_DISPLAY_NAME, 'test.gif'),
                         (mapitags.PR_ATTACH_DATA_BIN, f.read()),
                         ])
    f.close()
    iAttach[1].SaveChanges(0)
    
    message.SetProps([(mapitags.PR_BODY_A,Message),
                      (mapitags.PR_SUBJECT_A,Subject)])

    # save changes and submit
    outboxfolder.SaveChanges(0)
    message.SubmitMessage(0)

def test():
   MAPIProfile = "mail.sjsoft.com"
   SendTo = "shayan at telkomsa.net"
   SendCC = "shayanr at sjsoft.com"
   SendBCC = None
   SendMessage = "testing one two three"
   # SendSubject = "Testing Simple MAPI!!"
   # SendMAPIMail(SendSubject, SendMessage, SendTo, MAPIProfile=MAPIProfile)
   SendSubject = "Testing Extended MAPI!!"
   print SendSubject
   SendEMAPIMail(SendSubject, SendMessage, SendTo, MAPIProfile=MAPIProfile)

if __name__ == '__main__':

   MAPIProfile = ""
   # Change this to a valid email address to test
   SendTo = "an.invalid at address"
   SendMessage = "testing one two three"
   SendSubject = "Testing Extended MAPI!!"
   SendEMAPIMail(SendSubject, SendMessage, SendTo, MAPIProfile=MAPIProfile)


More information about the Python-win32 mailing list