1

I have written a method to save outlook email attachments into hard disk and convert the file into Base64String. When I was saving the attachments, the embedded (inline) images also getting saved, even though they are not REAL attachments. I wanted to save only the real attachments. Then I modified the method as follows. But now I'm getting an error from the line of ".OfType()".

Here is my code:

private string GetBase64StringForAttachments(Outlook.MailItem mailItem)
        {
            StringBuilder builder = new StringBuilder();
            Outlook.Attachments mailAttachments = mailItem.Attachments;
            
            try
            {                
                if (mailAttachments != null)
                {                    
                    Regex reg = new Regex(@"<img .+?>", RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    MatchCollection matches = reg.Matches(mailItem.HTMLBody);

                    for (int i = 1; i <= mailAttachments.Count; i++)
                    {
                        Outlook.Attachment currentAttachment = mailAttachments[i];

                        bool isMatch = matches
                          .OfType<Match>()
                          .Select(m => m.Value)
                          .Where(s => s.IndexOf("cid:" + currentAttachment.FileName, StringComparison.InvariantCultureIgnoreCase) >= 0)
                          .Any();

                        MessageBox.Show(currentAttachment.FileName + ": " + (isMatch ? "Inline Image" : "Attached Image"));

                        if (currentAttachment != null)
                        {
                            
                            string date = DateTime.Now.ToString("yyyymmddhhmmss");
                            string path = "C:\\test\\" + date + currentAttachment.FileName; //ToDo: Create Folder
                            currentAttachment.SaveAsFile(path);

                            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                            byte[] filebytes = new byte[fs.Length];
                            fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
                            string encodedData = Convert.ToBase64String(filebytes, Base64FormattingOptions.InsertLineBreaks);
                            builder.Append(encodedData).Append(",");

                            Marshal.ReleaseComObject(currentAttachment);
                        }
                    }

                    if (builder.Length > 0)
                    {                        
                        string encodedAttachments = builder.ToString().Remove(builder.ToString().Length-1);
                        return builder.ToString();
                    }
                    else
                        return "";

                }
                else return "";
            }
            catch (Exception ex)
            {
                Debug.DebugMessage(2, "Error in GetBase64StringForAttachments : in AddinModule " + ex.Message);
                return "";
            }
            finally
            {
                Marshal.ReleaseComObject(mailAttachments);                
            }
        }

This is the Error Message:

'System.Text.RegularExpressions.MatchCollection' does not contain a definition for 'OfType' and no extension method 'OfType' accepting a first argument of type 'System.Text.RegularExpressions.MatchCollection' could be found (are you missing a using directive or an assembly reference?)

What I need:

  1. I am not a big fan of LINQ. So, can you please advice me on this

  2. Is there a better way of doing this?

    I already tried followed the suggested answers for these questions and they did not work for me

Saving only the REAL attachments of an Outlook MailItem

Don't save embed image that contain into attachements (like signature image)

  1. Is there a way to use Redemption for distinguishing the real attachments?
Community
  • 1
  • 1
Kushan Randima
  • 2,174
  • 5
  • 31
  • 58
  • If you can't get the flags solutions to work, note that Microsoft changed the rules for flags and you have to use a different value for your check to make it work in Outlook 365. For details see this answer https://stackoverflow.com/a/70823130/1657610. – Reg Edit Jan 23 '22 at 14:42
  • @RegEdit, Thank you very much for your interest and the answer you shared with me. – Kushan Randima Jan 23 '22 at 21:30

2 Answers2

1

Yes, Redemption (I am its author) exposes the RDOAttachment.Hidden property - it checks the HTMLBody to make sure the attachment is not used as an inline image.

Also note that you can access the attachment data using RDOAtttachment.AsArray without saving the attachment as a file first.

Redemption.RDOSession rSession = new Redemption.RDOSession();
rSession.MAPIOBJECT = mailItem.Application.Session.MAPIOBJECT;
Redemption.RDOMail rMail= rSession.GetRDOFolderFromOutlookObject(mailItem)
foreach (Redemption.RDOAttachment attach in rMail.Attachments)
{
  if ((attach.Type == Redemption.rdoAttachmentType.olByValue) && (!attach.Hidden))
  {
     attach.SaveAsFile(path);
  }
}
next
Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
0
using Attachment = MsgReader.Outlook.Storage.Attachment;

foreach (Attachment attachment in mailItem.Attachments.Where(a => ((Attachment)a).Hidden == false)) {
  // do whatever you want with the 'real' attachments.
}
m b k
  • 145
  • 1
  • 4