【问题标题】:MailItem attachment unknownMailItem 附件未知
【发布时间】:2019-05-17 16:54:35
【问题描述】:

我有一封邮件,其中仅包含签名作为图像和如下截图所示的附件。

我将此电子邮件保存为C:\mail.msg,然后我尝试通过以下代码阅读它:

var oApp = new Microsoft.Office.Interop.Outlook.Application();
MailItem outlookMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItemFromTemplate(@"C:\mail.msg");

//there are 2 attachments inside
foreach(var att in outlookMsg.Attachments) 
{
    att.SaveAsFile($@"C:\{att.FileName}");
}

问题

MailItem 内有 2 个附件,命名为:

-empty.xlsx

-lot4.xlsx

如果我把lot4.xlsx的扩展名改成lot4.png,就可以作为签名中的图片打开了。

在添加名称不正确的附件时,有人见过这种奇怪的情况吗?

【问题讨论】:

  • 具体来说,您是如何查询文件名/扩展名的?您能否向我们展示您用于读取/检查名称的代码和属性?这要么是您偶然发现的 Outlook 互操作 API 中的一个非常奇怪的错误,要么是您自己代码中其他地方的一些问题。
  • @JᴀʏMᴇᴇ 当我保存文件时,我可以检查名称

标签: c# outlook mailitem


【解决方案1】:

您可以使用以下代码下载附件:

private void ThisApplication_NewMail()
{
    Outlook.MAPIFolder inBox = this.Application.ActiveExplorer()
        .Session.GetDefaultFolder(Outlook
        .OlDefaultFolders.olFolderInbox);
    Outlook.Items inBoxItems = inBox.Items;
    Outlook.MailItem newEmail = null;
    inBoxItems = inBoxItems.Restrict("[Unread] = true");
    try
    {
        foreach (object collectionItem in inBoxItems)
        {
            newEmail = collectionItem as Outlook.MailItem;
            if (newEmail != null)
            {
                if (newEmail.Attachments.Count > 0)
                {
                    for (int i = 1; i <= newEmail
                       .Attachments.Count; i++)
                    {
                        newEmail.Attachments[i].SaveAsFile
                            (@"C:\TestFileSave\" +
                            newEmail.Attachments[i].FileName);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        string errorInfo = (string)ex.Message
            .Substring(0, 11);
        if (errorInfo == "Cannot save")
        {
            MessageBox.Show(@"Create Folder C:\TestFileSave");
        }
    }
}

更多信息,请参考此链接:

How to: Programmatically save attachments from Outlook email items

【讨论】:

    【解决方案2】:

    使用Microsoft EWS,很容易做到:

    参考:http://johnlabtest.blogspot.com/2014/01/save-attachments-from-exchange-mail-box.html

    static void Main(string[] args)
    {
          ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
          service.Credentials = new WebCredentials("user1@contoso.com", "password");
          service.TraceEnabled = true;
          service.TraceFlags = TraceFlags.All;
          service.AutodiscoverUrl("user1@contoso.com", RedirectionUrlValidationCallback);
    
          var messages = new List<EmailMessage>();
    
          // only get unread emails
          SearchFilter folderSearchFilter = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
         // we just need the id in our results
         var itemView = new ItemView(10) {PropertySet = new PropertySet(BasePropertySet.IdOnly)};
    
         FindItemsResults<Item> findResults = service.FindItems(folder.Id, folderSearchFilter, itemView);
    
         foreach (Item item in findResults.Items.Where(i => i is EmailMessage))
         {
            EmailMessage message = EmailMessage.Bind(service, item.Id, new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments, ItemSchema.HasAttachments));
            messages.Add(message);
         }
    
      // loop through messages and call processemail here.
    }
    
    public static void ProcessEmail(EmailMessage message)
    {
         string saveDir = ConfigurationManager.AppSettings["AttachmentSaveDirectory"];
         if (message.HasAttachments)
         {
            foreach (Attachment attachment in message.Attachments.Where(a=> a is FileAttachment))
            {
                FileAttachment fileAttachment = attachment as FileAttachment;
                fileAttachment.Load(); // populate the content property of the attachment
    
                using (FileStream fs = new FileStream(saveDir + attachment.Name, FileMode.Create))
                {
                   using (BinaryWriter w = new BinaryWriter(fs))
                   {
                      w.Write(fileAttachment.Content);
                   }
                }
            }
        }
    message.IsRead = true;
    message.Update(ConflictResolutionMode.AutoResolve); // push changes back to server
    }
    
    private static bool RedirectionUrlValidationCallback(string redirectionUrl)
    {
         // The default for the validation callback is to reject the URL.
         bool result = false;
         Uri redirectionUri = new Uri(redirectionUrl);
         // Validate the contents of the redirection URL. In this simple validation
         // callback, the redirection URL is considered valid if it is using HTTPS
        // to encrypt the authentication credentials. 
        if (redirectionUri.Scheme == "https")
        {
           result = true;
        }
           return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 2013-12-23
      • 2019-07-08
      • 2017-11-18
      • 2018-07-25
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      相关资源
      最近更新 更多