2010-10-07 14 views
4

Je travaille sur un objet VSTO en C#. Lorsque je clique sur le bouton, je sauvegarde la pièce jointe dans un dossier. Mon problème est: quand j'ai un email riche avec une image dans la signature, j'ai un élément dans ma pièce jointe. Mais je ne veux pas sauver cette image. Outlook (application) cache cette pièce jointe dans la pièce jointe! Alors pourquoi ne pas me :-(Ne pas enregistrer l'image incorporée qui contient des pièces jointes (comme l'image de la signature)

Mon code est très simple:

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

Mais je ne trouve pas un test pour ne pas enregistrer l'image de la signature

Répondre

2

J'ai. trouver une partie de ma solution. lorsque vous créez un e-mail la taille de l'image embed est à 0. vous pouvez exclure cela.

Mais ce n'est pas juste quand je lis un email.

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

Quand j'ai lu un courriel, j'ai trouvé une solution, mais ce n'est pas très agréable. Alors je l'écris, mais si quelqu'un pense avoir mieux, j'aime ça. Dans mon exemple, j'essaie d'obtenir la propriété Flag avec PropertyAccessor, si c'est une image incorporée, c'est ok sinon j'ai une exception qui est 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); 
} 
2

voir que cette question a des + 2k coups et est toujours pas répondu, voici ma tentative d'une méthode utilitaire statique qui renvoie une liste des pièces jointes 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; 
} 
+0

Si vous êtes intéressé s'il vous plaît engager pour ceci: http: //stackoverflow.com/documentation/outlook-addin/commit –

4

Nous avions une besoin de montrer seulement les "pièces jointes" (pas les pièces jointes qui sont utilisées pour le rendu) dans un complément Outlook, et c'est ce qui fonctionne.

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

La solution de contournement des drapeaux ne fonctionnait pas pour moi. Je développe une solution pour Outlook 2016 et je réussi à filtrer les pièces jointes en utilisant ce 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 
       } 
    } 

qui vérifie essentiellement dans le corps HTML si chacune des pièces jointes est mentionné dans une balise.


EDIT: la méthode précédente peut sauter une pièce jointe si vous tapez son nom dans le corps. Cela est moins likey ignorer les faux positifs

if (!mailItem.HTMLBody.Contains("cid:" + attachment.FileName)) 
+1

La plupart des images sont désignées en HTML par le contenu id (cid). Vous devez rechercher à la fois le nom de fichier et l'ID de contenu (propriété MAP PR_ATTACH_CONTENT_ID - jetez un coup d'œil au message avec OutlookSpy). Votre code ne fonctionnera pas pour les identifiants de contenu. Si vous souhaitez également marquer de manière erronée les pièces jointes mentionnées dans le corps du message (par exemple, "Je joins TheFile.doc pour votre avis") –