【问题标题】:Don't save embed image that contain into attachements (like signature image)不要将包含的嵌入图像保存到附件中(如签名图像)
【发布时间】:2011-04-22 06:36:12
【问题描述】:

我在 C# 中处理 VSTO。当我单击按钮时,我将附件保存在文件夹中。我的问题是:当我有一封带有签名图片的丰富电子邮件时,我的附件中有一个元素。但我不想保存该图像。 Outlook(应用程序)将此附件隐藏在附件区域中!那为什么不是我呢:-(

我的代码很简单:

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

但我没有找到不保存签名图像的测试。

【问题讨论】:

    标签: c# vsto attachment outlook-addin


    【解决方案1】:

    2022 年 Outlook 365 的新答案

    标志的答案对我不起作用,所以我开始调查调试器中发生了什么。

    我发现微软明显改变了标志的规则,因为我在调试器中看到的值与旧标志解决方案中给出的值不匹配。

    要让它今天在 Outlook 365 中工作,只需忽略标志不为 0 的附件:

        var flags = attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37140003");
    
        if (flags == 0)
        {
          //
          // Normal attachment, not embedded image etc, so save it
          //
        }
    

    【讨论】:

      【解决方案2】:

      标志解决方法对我不起作用。我正在为 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))
      

      【讨论】:

      • 大多数图像在 HTML 中由内容 id (cid) 引用。您需要同时查看文件名和内容 ID(PR_ATTACH_CONTENT_ID MAPI 属性 - 使用 OutlookSpy 查看消息)。您的代码不适用于内容 ID。 If 还会错误地标记邮件正文中提到的附件(例如“我正在附加 TheFile.doc 以供您查看”)
      • 终于是一个不错的答案,不依赖于旧的和已删除的 Windows 架构!
      【解决方案3】:

      我们需要在 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);
                          }
      
                      }
      
                  }
              }
      

      【讨论】:

        【解决方案4】:

        看到这个问题有一些 +2k 的点击率并且仍然没有得到回答,这是我对返回非内联附件列表的静态实用程序方法的尝试:

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

        【讨论】:

        【解决方案5】:

        我找到了解决方案的一部分。 当您创建电子邮件时,图像嵌入的大小为 0。因此您可以排除它。

        但是当我阅读电子邮件时它是不对的。

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

        当我阅读电子邮件时,我找到了一个解决方案,但它不是很好。所以我写了它,但如果有人认为有更好的,我喜欢它。 在我的示例中,我尝试使用 PropertyAccessor 获取 Flag 属性,如果它是嵌入图像,那没关系,否则我会引发异常。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-09-14
          • 2019-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-13
          • 2021-03-17
          相关资源
          最近更新 更多