Outlook pywin32和扩展mapi:发送带有附件的电子邮件

Outlook pywin32和扩展mapi:发送带有附件的电子邮件,outlook,email-attachments,pywin32,mapi,Outlook,Email Attachments,Pywin32,Mapi,我正在使用以下代码通过简单的MAPI界面发送电子邮件 import win32com.client olMailItem = 0x0 obj = win32com.client.Dispatch("Outlook.Application") newMail = obj.CreateItem(olMailItem) newMail.Subject = "I AM SUBJECT!!" newMail.Body = "I AM IN THE BODY\nSO AM I!!!" newMail.To

我正在使用以下代码通过简单的MAPI界面发送电子邮件

import win32com.client
olMailItem = 0x0
obj = win32com.client.Dispatch("Outlook.Application")
newMail = obj.CreateItem(olMailItem)
newMail.Subject = "I AM SUBJECT!!"
newMail.Body = "I AM IN THE BODY\nSO AM I!!!"
newMail.To = "themail@mail.org"
#newMail.CC = "moreaddresses here"
#newMail.BCC = "aaa"
#attachment1 = "Path to attachment no. 1"
#attachment2 = "Path to attachment no. 2"
#newMail.Attachments.Add(attachment1)
#newMail.Attachments.Add(attachment2)
#newMail.display()
newMail.Send()
它似乎在Outlook 2007/2010中也能工作,但它显示了发送邮件的警告


我是否可以使用扩展MAPI发送电子邮件而不显示警告以及发送附件?如果是,在哪里可以找到示例

>不,不能用Python使用扩展,需要C++或Delphi。
您可以选择安装一个最新的防病毒应用程序或使用扩展的MAPI包装器,例如./P>< P>不,您不能使用Python使用扩展,您需要C++或Delphi。
您的选项位于-您可以安装最新的防病毒应用程序,也可以使用扩展的MAPI包装,例如。

对不起,我说的是英语。
我找到了使用PyWin32在扩展mapi上添加附件的解决方案…
这个密码不是我的。。我只添加了附件部分。
这将以html格式或文本格式向outlook发送邮件,包括嵌入html中的附件(图像)和其他附件。
附件可以是每种类型的文件(.txt、.pdf、ecc-ecc)
在此示例代码中,html页面和附件文件必须位于此py代码的同一目录中

Outlook必须正常工作才能成功运行此代码。。 请参阅MAPILogonEx
它使用outlook发送邮件。。因此,如果您是在私人网络上,那么Autenticathion部分只需运行Outlook本身即可完成:)

(感谢Mark Hammond提供的PyWin32!)
(感谢德米特里·斯特雷布列琴科的《了望间谍》!)


从win32com.mapi导入mapi
从win32com.mapi导入mapitags
从win32com.mapi.mapitags导入PROP_标记、PT_UNICODE、PT_二进制
导入操作系统
def Add_Message_AttachList(Message,AttachList,PathAttach,ContentIDList=None):
"""
向邮件添加附件列表
:param Message:附加列表的字符串消息
:param AttachList:字符串逗号分隔的附件列表
:param PathAttach:附件的字符串路径
:param ContentIDList:如果未嵌入附件,则字符串无
以逗号分隔的ContentsID列表(如果嵌入)
"""
#定义了一些共因
方法=0
渲染=1
路径=2
长路径=3
文件名=4
显示名称=5
数据_BIN=6
NUM_ATT_PROPS=7
如果ContentIDList:
CONTENT_ID=7
NUM_ATT_PROPS=8
ID_List=ContentIDList.split(“,”)
从集合导入namedtuple
sPropValue=namedtuple(“sPropValue”、“ulPropTag值”)
文件名索引=0
对于AttachList.split(“,”)中的文件名:
我的文件=打开(路径附加+“/”+文件名,“rb”)
file\u buffer=my\u file.read()
我的_文件。关闭()
spvAttach=['']*NUM_ATT_PROPS
spvatach[METHOD]=sPropValue(mapitags.PR\u ATTACH\u方法,mapi.ATTACH\u BY\u值)
spvAttach[RENDERING]=sPropValue(mapitags.PR_RENDERING_位置,-1)
spvAttach[PATH]=sPropValue(mapitags.PR_ATTACH_路径名,路径附加+“/”+文件名)
spvAttach[LONG_PATH]=sPropValue(mapitags.PR_ATTACH_LONG_路径名,路径附加+“/”+文件名)
spvAttach[FILENAME]=sPropValue(mapitags.PR\u ATTACH\u文件名、文件名)
spvatach[DISPLAY\u NAME]=sPropValue(mapitags.PR\u DISPLAY\u NAME\u A,文件名)
spvatach[DATA\u BIN]=sPropValue(mapitags.PR\u ATTACH\u DATA\u BIN,文件\u缓冲区)
#定义pywin32 mapitags中未定义的属性PR_ATTACH_CONTENT_ID_。
#MSDN库中的PR_ATTACH_CONTENT_ID_W属性数
# https://msdn.microsoft.com/en-us/library/cc765868.aspx
#所有mapi标记都在中定义https://msdn.microsoft.com/en-us/library/cc815492%28v=office.15%29.aspx
mapitags.PR_ATTACH_CONTENT_ID_W=PROP_标记(PT_UNICODE,0x3712)
如果ContentIDList:
spvatach[CONTENT\u ID]=sPropValue(mapitags.PR\u ATTACH\u CONTENT\u ID\u W,ID\u List[文件名\u索引])
文件名索引+=1
#创建附件
pAtt=Message.CreateAttach(无,0)
#设置附件的属性
pAtt[1]。SetProps(spvAttach)
#保存附件的属性
pAtt[1]。保存更改(0)
#-------------------------结束添加消息附件列表----
def SendEMAPIMail(是HTML,主题=”,消息文本=”,sendAttachs=None,SENDATTACHEMBEDEDDS=None,
sendAttachEmbeddedIDs=无,
sendTo=None、sendCC=None、sendBCC=None、mAPIProfile=None):
"""
使用扩展MAPI接口向收件人发送电子邮件
主题和消息文本是字符串
sendAttachs是一个逗号分隔的附件列表
Send{To,CC,BCC}是逗号分隔的地址列表
MAPI配置文件是MAPI配置文件的名称
"""
myPathFile=os.getcwdu()
#初始化并登录
mapi.MAPIInitialize(无)
会话=mapi.MAPIGONEX(0,MAPIGROFILE,无,mapi.mapi_扩展| mapi.mapi_使用_默认值)
messagestorestable=session.GetMsgStoresTable(0)
messagestorestable.SetColumns((mapitags.PR\u ENTRYID,mapitags.PR\u DISPLAY\u NAME\u A,mapitags.PR\u DEFAULT\u STORE),0)
尽管如此:
rows=messagestorestable.QueryRows(1,0)
如果len(行)!=1:
打破
行=行[0]
如果行中有(mapitags.PR_DEFAULT_STORE,True):
打破
#解包该行并打开消息存储
(eid_标签,eid),(名称_标签,名称),(def_存储_标签,def_存储)=行
msgstore=session.OpenMsgStore(0,eid,None,mapi.MDB_NO_对话框| mapi.mapi_最佳访问)
#拿到发件箱
hr,props=msgstore.GetProps(mapitags.PR\u IPM\u OUTBOX\u ENTRYID,0)
(标签,eid)=道具[0]
outboxfolder=msgstore.OpenEntry(eid,无,mapi.mapi\u最佳访问)
#创建消息和addrlist
message=outboxfolder.CreateMessage(无,0)
#注意:您可以为此使用resolveaddress函数。但是你可能会头疼
pal=[]
def生成条目(r
from win32com.mapi import mapi
from win32com.mapi import mapitags
from win32com.mapi.mapitags import PROP_TAG, PT_UNICODE, PT_BINARY

import os


def Add_Message_AttachList(Message, AttachList, PathAttach, ContentIDList = None):

    """
    Add  a AttachList to a message

    :param Message: string       message for the Attach list
    :param AttachList: string    comma separated list of attachments
    :param PathAttach:  string   path of the attachments
    :param ContentIDList: string None if attachments aren't embedded
                                 comma separated list of ContentsID if embedded

    """

    # defines some costants
    METHOD = 0
    RENDERING = 1
    PATH = 2
    LONG_PATH = 3
    FILENAME = 4
    DISPLAY_NAME = 5
    DATA_BIN = 6
    NUM_ATT_PROPS = 7

    if ContentIDList:
        CONTENT_ID = 7
        NUM_ATT_PROPS = 8
        ID_List = ContentIDList.split(",")

    from collections import namedtuple

    sPropValue = namedtuple("sPropValue", "ulPropTag Value")
    file_name_index = 0
    for file_name in AttachList.split(","):

        my_file = open(PathAttach + "//" + file_name, "rb")
        file_buffer = my_file.read()
        my_file.close()

        spvAttach = [''] * NUM_ATT_PROPS
        spvAttach[METHOD] = sPropValue(mapitags.PR_ATTACH_METHOD, mapi.ATTACH_BY_VALUE)
        spvAttach[RENDERING] = sPropValue(mapitags.PR_RENDERING_POSITION, -1)
        spvAttach[PATH] = sPropValue(mapitags.PR_ATTACH_PATHNAME, PathAttach + "//" + file_name)
        spvAttach[LONG_PATH] = sPropValue(mapitags.PR_ATTACH_LONG_PATHNAME, PathAttach + "//" + file_name)
        spvAttach[FILENAME] = sPropValue(mapitags.PR_ATTACH_FILENAME, file_name)
        spvAttach[DISPLAY_NAME] = sPropValue(mapitags.PR_DISPLAY_NAME_A, file_name)
        spvAttach[DATA_BIN] = sPropValue(mapitags.PR_ATTACH_DATA_BIN, file_buffer)


        # defines the property PR_ATTACH_CONTENT_ID_W  not defined  in pywin32 mapitags.
        # number of PR_ATTACH_CONTENT_ID_W Property is in MSDN Library
        # https://msdn.microsoft.com/en-us/library/cc765868.aspx
        # all mapi tags are defined in https://msdn.microsoft.com/en-us/library/cc815492%28v=office.15%29.aspx
        mapitags.PR_ATTACH_CONTENT_ID_W = PROP_TAG(PT_UNICODE, 0x3712)

        if ContentIDList:
            spvAttach[CONTENT_ID] = sPropValue(mapitags.PR_ATTACH_CONTENT_ID_W, ID_List[file_name_index])

        file_name_index += 1
        # create a attachment
        pAtt = Message.CreateAttach(None, 0)
        # set the properties of the attachment
        pAtt[1].SetProps(spvAttach)
        # save the properties of the attachment
        pAtt[1].SaveChanges(0)

# ----------------------End Add_Message_AttachList ----



def SendEMAPIMail(is_HTML, subject = "", messageText = "", sendAttachs = None, sendAttachEmbeddeds = None,
                  sendAttachEmbeddedIDs = None,
                  sendTo = None, sendCC = None, sendBCC = None, mAPIProfile = None):
    """
    Sends an email to the recipient using the extended MAPI interface

    subject and messageText are strings
    sendAttachs is a comma-separated attachments list
    Send{To,CC,BCC} are comma-separated address lists
    MAPIProfile is the name of the MAPI profile
    """

    myPathFile = os.getcwdu()
    # 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]
        if (mapitags.PR_DEFAULT_STORE, True) in row:
            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)

    # add attachments
    if sendAttachs:
        Add_Message_AttachList(message, sendAttachs, myPathFile, None)
    # add attachments embedded in the html message
    if sendAttachEmbeddeds:
        Add_Message_AttachList(message, sendAttachEmbeddeds, myPathFile, sendAttachEmbeddedIDs)


    if is_HTML:
        # defines the property PR_HTML  not defined  in pywin32 mapitags.
        # number of PR_HTML Property is in MSDN Library
        # https://msdn.microsoft.com/en-us/library/cc842395.aspx
        # all mapi tags are defined in https://msdn.microsoft.com/en-us/library/cc815492%28v=office.15%29.aspx
        mapitags.PR_HTML = PROP_TAG(PT_BINARY, 0x1013)
        message.SetProps([(mapitags.PR_HTML, messageText),
                          (mapitags.PR_SUBJECT_W, subject)])
    else:
        message.SetProps([(mapitags.PR_BODY_W, messageText),
                          (mapitags.PR_SUBJECT_W, subject)])


    # save changes and submit
    outboxfolder.SaveChanges(0)
    message.SubmitMessage(0)
    # close the extended mapi session
    # session.Logoff(0, 0, 0)

# ------------------END  SendEMAPIMail------



if __name__ == '__main__':
    # initialize....
    MAPIProfile = ""
    ImageEmbeddeds = None
    ImageEmbeddedIDs = None
    is_HTML = True    # if True il messaggio has html format
                      # else the message has text format.

    # list_to

    SendTo = "abc@xy.it,cdef@mail.it"

        # subject message
    SendSubject = "Paperino HTML"

        # simple text message
    s = "text message"

    if is_HTML:
        # my_page.html  is the message with HTML format
        mio_file = open("my_page.html", "rb")
        s = mio_file.read()
        mio_file.close()
        ImageEmbeddeds = "paperino.jpg"  # image HTML list, None for none immagine
        ImageEmbeddedIDs = "paperino"    # imageID HTML list, None for none ID

    SendMessage = s
        # attach list  , None for  no file.
    SendAttachs = "file1.txt"




    SendEMAPIMail(is_HTML, SendSubject, SendMessage,
                  SendAttachs, ImageEmbeddeds, ImageEmbeddedIDs,
                  SendTo, None, None, MAPIProfile)
    print "Done!"

-----------------------------------------------------------------------------
my_page.html
HTML File..  image attribute cid is the same into ImageEmbeddedIDs
this html code is commented for viewing
<!--
<!doctype html>
<html lang="it">
    <head>
        <meta 
            http-equiv="Content-Type" 
            content="text/html; charset = utf-8" 
        />  
        <title>Paperino</title>
    </head>
    <body>
        <p align="center">
          <img src="cid:paperino" width="77" height="77">
          <p align="center">Hi to all!</p>
          <hr align="left" size="1">
          <p align="left">Amd</p>
        </p>
    </body>
</html>     

-->