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

我与影子孤独终老i 提交于 2019-12-29 07:55:08

问题


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 attachment. But I don't want save that image. Outlook (application) hide this attachment in the area attachment ! So why not me :-(

My code is very simply :

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

But I don't find a test for don't save the image of the signature.


回答1:


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

                }

            }
        }



回答2:


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



回答3:


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;
}



回答4:


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


来源:https://stackoverflow.com/questions/3880346/dont-save-embed-image-that-contain-into-attachements-like-signature-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!