Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Don';t保存包含在附件中的嵌入图像(如签名图像)_C#_Vsto_Attachment_Outlook Addin - Fatal编程技术网

C# Don';t保存包含在附件中的嵌入图像(如签名图像)

C# Don';t保存包含在附件中的嵌入图像(如签名图像),c#,vsto,attachment,outlook-addin,C#,Vsto,Attachment,Outlook Addin,我在c#中的VSTO上工作。当我点击按钮时,我将附件保存在一个文件夹中。我的问题是:当我有一封签名中有图像的丰富电子邮件时,我的附件中就有一个元素。但我不想保存那张照片。Outlook(应用程序)在附件区域中隐藏此附件!那为什么不是我呢-( 我的代码非常简单: MailItem MailItemSelected = this.OutlookItem; foreach (Attachment a in MailItemSelected.Attachments) { a.SaveAsF

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

我的代码非常简单:

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

但是我没有找到一个测试,用于不保存签名的图像。

我找到了解决方案的一部分。 创建电子邮件时,图像嵌入的大小为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);
}

看到这个问题有+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;
}
//
///方法获取所有非内联附件(如图像和内容)的附件。
/// 
/// 
///邮件。
/// 
/// 
///这个。
/// 
公共静态列表GetMailAttachments(Outlook.MailItem-MailItem){
常量字符串PR_ATTACH_方法=”http://schemas.microsoft.com/mapi/proptag/0x37050003";
常量字符串PR_ATTACH_标志=”http://schemas.microsoft.com/mapi/proptag/0x37140003";
var attachments=新列表();
//如果这是纯文本电子邮件,则每个附件都是非内联附件
如果(mailItem.BodyFormat==Outlook.OlBodyFormat.olFormatPlain&&mailItem.Attachments.Count>0){
附件.AddRange(
mailItem.Attachments.Cast().Select(attachment=>attachment as Outlook.attachment));
归还附件;
}
//如果正文格式为RTF。。。
if(mailItem.BodyFormat==Outlook.OlBodyFormat.olFormatRichText){
//添加PR_ATTACH_METHOD属性不是6的每个附件(ATTACH_OLE)
附件.AddRange(
mailItem.Attachments.Cast()。选择(附件=>作为Outlook.attachment的附件)。其中(thisAttachment=>(int)thisAttachment.PropertyAccessor.GetProperty(PR_attachment_方法)!=6));
}
//如果正文格式是HTML。。。
if(mailItem.BodyFormat==Outlook.OlBodyFormat.olFormatHTML){
//添加ATT_MHTML_REF属性不是4的每个附件(ATT_MHTML_REF)
附件.AddRange(
mailItem.Attachments.Cast()。选择(附件=>作为Outlook.attachment的附件)。其中(thisAttachment=>(int)thisAttachment.PropertyAccessor.GetProperty(PR_attachment_标志)!=4));
}
归还附件;
}

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

                }

            }
        }

标志解决方案不适用于我。我正在为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正文中检查标记中是否提到了每个附件


编辑:如果您在正文中键入附件的名称,前面的方法可能会跳过附件。这不太可能跳过误报


如果您对此感兴趣,请提交:此代码仅检查内联附件。问题是区分签名附件(如签名中的徽标图像)和“其他附件”可能为内联或普通的其他附件。大多数图像在HTML中由内容id(cid)引用。您需要同时查看文件名和内容id(PR_ATTACH_content_id MAPI属性-使用OutlookSpy查看邮件)。您的代码将不适用于内容id。If还会错误地标记邮件正文中提到的附件(例如,“我正在附加file.doc供您审阅”)
if (!mailItem.HTMLBody.Contains("cid:" + attachment.FileName))