Не сохраняйте встроенное изображение, которое содержит вложения (например, изображение подписи) - PullRequest
4 голосов
/ 07 октября 2010

Я работаю над VSTO в c #. Когда я нажимаю на кнопку, я сохраняю вложение в папке. Моя проблема в том, что, когда у меня электронное письмо с изображением в подписи, в приложении есть элемент. Но я не хочу сохранять это изображение. Outlook (приложение) скрывает это вложение в области вложений! Так почему не я: - (

Мой код очень прост:

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

Но я не могу найти тест, чтобы не сохранить изображение подписи.

Ответы [ 4 ]

5 голосов
/ 12 января 2015

Нам нужно было показать только «почтовые вложения» (а не встроенные, используемые для рендеринга) в надстройке Outlook, и это то, что работает.

 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 голосов
/ 11 февраля 2014

видя, что этот вопрос имеет несколько +2 тыс. Обращений и до сих пор не получен ответ, вот моя попытка использования статического служебного метода, который возвращает список вложений NON INLINE:

/// <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;
}
2 голосов
/ 08 октября 2010

Я нашел одну часть моего решения. Когда вы создаете электронное письмо, размер вставляемого изображения равен 0. Таким образом, вы можете исключить это.

Но это неправильно, когда я читаю письмо.

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

Когда я читал электронную почту, я нашел решение, но оно не очень хорошее. Поэтому я пишу это, но если кто-то думает, что лучше, мне это нравится. В моем примере я пытаюсь получить свойство Flag с помощью PropertyAccessor, если это встраиваемое изображение, все нормально, у меня есть исключение, которое будет повышено.

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 голосов
/ 19 апреля 2017

Обход флагов у меня не сработал. Я разрабатываю решение для Outlook 2016, и мне удалось отфильтровать вложения с помощью этого кода:

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

, который в основном проверяет в теле HTML, упоминается ли каждое из вложений в теге.


РЕДАКТИРОВАТЬ: предыдущий метод может пропустить вложение, если вы введете его имя в теле. Это менее вероятно, чтобы пропустить ложные срабатывания

if (!mailItem.HTMLBody.Contains("cid:" + attachment.FileName))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...