Don't save embed image that contain into attachements (like signature image)

前端 未结 4 1567
一向
一向 2020-12-19 15:05

I work on a VSTO in c#. When I click on button I save attachment in a folder. My problem is : when I have a rich email with an image in the signature, I have a element in my

相关标签:
4条回答
  • 2020-12-19 15:29

    We had a need to show only the "Mail Attachments" (not the embedded ones that are used for rendering) in an Outlook Add - In, and this is what that works.

     if (mailItem.Attachments.Count > 0)
            {
                // get attachments
                foreach (Attachment attachment in mailItem.Attachments)
                {
                    var flags = attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37140003");
    
                    //To ignore embedded attachments -
                    if (flags != 4)
                    {
                        // As per present understanding - If rtF mail attachment comes here - and the embeded image is treated as attachment then Type value is 6 and ignore it
                        if ((int)attachment.Type != 6)
                        {
    
                            MailAttachment mailAttachment = new MailAttachment { Name = attachment.FileName };
                            mail.Attachments.Add(mailAttachment);
                        }
    
                    }
    
                }
            }
    
    0 讨论(0)
  • 2020-12-19 15:36

    I've find one part of my solution. When you create an email the size of image embed is to 0. So you can exclude this.

    But it is not right when I read a email.

    MailItem MailItemSelected =  this.OutlookItem;   
    foreach (Attachment a in MailItemSelected.Attachments)
    {                                    
       if(a.Size != 0)
          a.SaveAsFile(path + a.FileName);
    }
    

    When I read email I found a solution, but it is not very nice. So I write it, but if anybody think have better, I like it. In my example I try to get the Flag property with the PropertyAccessor, if it's a embed image, it's ok else I've an exception that be raise.

    MailItem MailItemSelected =  this.OutlookItem;   
    foreach (Attachment a in MailItemSelected.Attachments)
    {
       bool addAttachment = false;
       try
       {
          string schemaPR_ATTACH_FLAGS = "http://schemas.microsoft.com/mapi/proptag/0x37140003"; 
          a.PropertyAccessor.GetProperty(schemaPR_ATTACH_FLAGS);
       }
       catch
       {
          addAttachment = true;
       }
    
       if (addAttachment && (a.Size != 0))
          a.SaveAsFile(path + a.FileName);
    }
    
    0 讨论(0)
  • 2020-12-19 15:51

    seeing that this question has some +2k hits and is still not answered, here is my attempt at a static utility method that returns a list of NON INLINE attachments:

    /// <summary>
    /// Method to get all attachments that are NOT inline attachments (like images and stuff).
    /// </summary>
    /// <param name="mailItem">
    /// The mail item.
    /// </param>
    /// <returns>
    /// The <see cref="List"/>.
    /// </returns>
    public static List<Outlook.Attachment> GetMailAttachments(Outlook.MailItem mailItem) {
        const string PR_ATTACH_METHOD = "http://schemas.microsoft.com/mapi/proptag/0x37050003";
        const string PR_ATTACH_FLAGS = "http://schemas.microsoft.com/mapi/proptag/0x37140003";
    
        var attachments = new List<Outlook.Attachment>();
    
        // if this is a plain text email, every attachment is a non-inline attachment
        if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain && mailItem.Attachments.Count > 0) {
            attachments.AddRange(
                mailItem.Attachments.Cast<object>().Select(attachment => attachment as Outlook.Attachment));
            return attachments;
        }
    
        // if the body format is RTF ...
        if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatRichText) {
            // add every attachment where the PR_ATTACH_METHOD property is NOT 6 (ATTACH_OLE)
            attachments.AddRange(
                mailItem.Attachments.Cast<object>().Select(attachment => attachment as Outlook.Attachment).Where(thisAttachment => (int)thisAttachment.PropertyAccessor.GetProperty(PR_ATTACH_METHOD) != 6));
        }
    
        // if the body format is HTML ...
        if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatHTML) {
            // add every attachment where the ATT_MHTML_REF property is NOT 4 (ATT_MHTML_REF)
            attachments.AddRange(
                mailItem.Attachments.Cast<object>().Select(attachment => attachment as Outlook.Attachment).Where(thisAttachment => (int)thisAttachment.PropertyAccessor.GetProperty(PR_ATTACH_FLAGS) != 4));
        }
    
        return attachments;
    }
    
    0 讨论(0)
  • 2020-12-19 15:55

    The flags workaround didn't work for me. I'm developing a solution for Outlook 2016 and I managed to filter the attachments using this code:

    foreach (Attachment attachment in mailItem.Attachments)
                {
                    //exclude inline images
                    if (!mailItem.HTMLBody.Contains(attachment.FileName))
                    {
                        //the attachment is not an inline attachment, YOUR CODE HERE
                    }
        }
    

    which is basically checking in the HTML body if each of the attachments is mentioned in a tag.


    EDIT: the previous method may skip an attachment if you type its name in the body. This is less likey to skip false positives

    if (!mailItem.HTMLBody.Contains("cid:" + attachment.FileName))
    
    0 讨论(0)
提交回复
热议问题