Converting a Outlook mail attachment to byte array with C# - c#

Fair warning: I'm a little bit of a rookie to C# and to Outlook, so bear with me on this.
I've been experimenting with emails in Outlook for a quick and dirty addin I'm building, but the addin requires me to send attached files to a different system.
Long story short; in order to do this I need to convert an Outlook item's mail attachment into a byte array.
What I have thus far (and the complete code is obviously miles longer than this, but I'm sure we all have better things to do than to sit and read page up and page down of code):
Outlook.Selection sel = control.Context as Outlook.Selection;
Outlook.MailItem mail = sel[1];
Outlook.Attachment a = mail.Attachments[0];
Problem is, that I have no idea how to convert a to a byte array.
PS: I know there are about a billion answers as to how to convert a byte array to a mail, but none to explain how to get it running the other way around.
EDIT 1: I would rather not have to save the file.

The second method proposed by Dmitry (open attachment as binary stream) is also achievable in managed code. It uses the PropertyAccessor interface, which is available for Attachment objects in C#. Here is some sample code I've used successfully in my own project:
const string PR_ATTACH_DATA_BIN = "http://schemas.microsoft.com/mapi/proptag/0x37010102";
Outlook.Attachment attachment = mail.Attachments[0];
// Retrieve the attachment as a byte array
var attachmentData =
attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_BIN);
My example code is based on the How to: Modify an Attachment of an Outlook Email Message topic provided by Ken Getz, MCW Technologies, LLC as part of the MSDN documentation.

You can either
Save the attachment (Attachment.SaveAsFile) to a file, then open the file as a byte stream.
If you were using C++ or Delphi, you could use IAttach::OpenProperty(PR_ATTACH_DATA_BIN, IID_IStream, ..) to open the attachment as IStream COM object.
If using Redemption is an option (I am its author), it exposes the AsArray property on the Attachment and RDOAttachment objects.

Related

Getting the attachment contents of an rtf mail in vsto c#

we are trying to get the content of the attachment's of the in the rtf mail but I have tried to search using different terms but have not found any reliable solution . can someone please help me to get the source of the attachment's as we get them in the html format.
The Outlook object model doesn't provide any property or method for getting the attachment content. To get the file attached you need to save it to the disk and then read the content from the there.
Also you may consider using a low-level API on which Outlook is based on - Extended MAPI. It allows getting the binary data of the attached file. Try using the Attachment.PropertyAccessor.GetProperty method while passing in the value "http://schemas.microsoft.com/mapi/proptag/0x37010102" (PR_ATTACH_DATA_BIN).
set msg = Application.ActiveExplorer.Selection(1)
set attach = msg.Attachments(1)
set ps = attach.PropertyAccessor
v = ps.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37010102")
debug.print ps.BinaryToString(v)
On the low level (Extended MAPI in C++ or Delphi), you need to open the PR_ATTACH_DATA_OBJ property as IStorage and extract the data from there (it depends on the actual type of the attachment). You can see the data in the streams in OutlookSpy (I am its author) - select the message, click IMessage button on the OutlookSpy ribbon, go to the GetAttachmentTable tab, double click on the attachment to open it, select the PR_ATTACH_DATA_OBJ property, right click, select IMAPIProp::OpenProperty, then IStorage. Raw data will be there as well as an image representing the attachment (so that Outlook won't have to start the host app when rendering the message).
If using Redemption is an option (I am also its author, it can be used from any language including C# and VBA), its version of RDOAttachment.SaveAsFile method handles OLE attachments for most popular formats (Word, Excel, bitmap, Power Point, Adobe PDF, etc.) - create an instance of the RDOSession object (using either CrealeOleObject or RedemptionLoader) and use RDOSession.GetRDOObjectFromOutlookObject method (pass either MailItem or Attachment object) to get back RDOMail or RDOAttachment object respectively.
i have been found a solution for getting the images content from the rtf mail directly whiteout hitting the low level api or anything.
the solution is not a straight forward one
save the mail to the disk using oDoc.SaveAs2(filepath, WdSaveFormat.wdFormatFilteredHTML);
after saving the mail you will get the folder which you save a .htm doc
now read the .htm doc
get the all the image nodes of the .htm doc
using the image nods you can get src attribute of the image node
using the src value of the image you get the image directly from the disk itself and you can use that image

Convert Outlook.Mailitem to MIME type without saving or sending the mail

I have a Outlook.Mailitem type object and I have to sent this object to a REST service so in order to do so either I have to convert Outlook.Mailitem to MIME type or Memory Stream type or in Bytes without disrupting the mail format since mail may contain attachments, images.
Is there a way we can convert Outlook.Mailitem to MIME type in C# without sending or saving the mail.
Thanks
Outlook comes with its own MIME converter - IConverterSession. You can play with it in OutlookSpy (I am its author - click IConverterSession button | MAPIToMIMEStm). Since this is an Extended MAPI interface, it is only accessible from C++ or Delphi.
Another option is creating a MIME message one header and one MIME part at a time from the MailItem object properties.
If using Redemption (any language, I am also its author) is an option, it exposes SafeMailItem.SaveAs and RDOMail.SaveAs method; one of the supported formats is MIME (olRfc822 = 1024).
See IConverterSession::MAPIToMIMEStm which converts a MAPI message to a MIME stream.
A sample code of using the MAPIToMIMEStm method can be found in MFCMAPI.

Convert EML to MSG c# Using EWS

I need help with converting EML to MSG, using the Exchange web service (EWS) in a Outlook Web Add-In. When i create an EML file from the MimeContent (EmailMessage.MimeContent.Content), the file output looks bad, some tags are not convert currently.
The files open good just from Windows mail app, but from Ooutlook(2016) looks bad.
I tried to find some solution from Microsoft and found this Independentsoft, a third party solution, and it is work great. the file looks good while the format is MSG. but it is to expansive licence solution for the customer (used 30 days demo).
This is what i used and work well, and try to found something like this:
//1.This code use the EWS mimeContent(the message on bytes - eml format)
//2.Create Independentsoft message object
//Independentsoft.Msg.Message constractor do the convert by
// making an msg object from an eml object.
//3. save the msg file.
Independentsoft.Email.Mime.Message mimeMessage = new Independentsoft.Email.Mime.Message(emailMessage.MimeContent.Content);
Independentsoft.Msg.Message msgMessage = Independentsoft.Msg.Message(mimeMessage);
using (MemoryStream memStream = new MemoryStream(emailMessage.MimeContent.Content.Length))
{
Directory.CreateDirectory(TempMsgDirectory);
msgMessage.Save(TempMsgDirectory + "mail.msg", true);
}
I am not aware of any Outlook problems with displaying EML files. It uses the same EML parser used to parse incoming POP3/IMAP4 messages. Please post a specific EML file that Outlook does not display correctly.
As for converting EML files to MSG, you can also use Redemption (I am its author) and its RDOSession.CreateMessageFromMsgFIle and RDOMail.Import methods. Just keep in mind that it requires the MAPI system to be present to function properly, which means Outlook must be installed locally.
Off the top of my head:
RDOSession session = new RDOSession();
RDOMail msg = session.CreateMessageFromMsgFile(TempMsgDirectory + "mail.msg");
msg.Import(TempMsgDirectory + "YouEmlFile.eml", rdoSaveAsType.olRFC822);
msg.Save();
Also keep in mind that retrieving MIME content from Exchange might not be the best idea - you will lose all MAPI specific properties and will end up with a corrupted message if the original was in the RTF format (with or without embedded OLE objects). In that case, you can use ExportItems EWS operation. Its format is not documented, but it is very close to the MSG format, and you can convert it to MSG using code similar to that above, but specifying olFTS format instead of olRFC822.

Converting .MSG files to .TXT; Should I use Microsoft.Interop Outlook?

I'm trying to do a conversion from .msg files into .txt. I have two questions.
1)I've been investigating and found the Microsoft.Interop Outlook package and there is a way where I can extract the bodyHTML, To, Sent Date, and a few other properties but I feel as if this is a very manual process because I have to trim out all the html tags such as < br>, &nbsp, a href etc...
Here is my current code...
MailItem mailItem = outlookApp.Session.OpenSharedItem(item) as MailItem;
TextFile textFile = new TextFile(); //collection of properties I am interested in
textFile.To = mailItem.To;
textFile.Subject = mailItem.Subject;
textFile.Sent = mailItem.SentOn.ToString();
textFile.Name = Path.GetFileNameWithoutExtension(item);
var atttach = mailItem.Attachments; //Really just want the names
textFile.Body = RemoveStuff(mailItem.HTMLBody); //manually removing all html tags
textFiles.Add(textFile);
Marshal.ReleaseComObject(mailItem);
Does anyone know if there is a more effective way to do this in C# or a way using Interop that I am not aware of?
2)If I go the interop route, is there a way I can bypass the popup in Outlook asking if I can allow access to Outlook? Seems inefficient if my goal is to create a converter.
Any help is greatly appreciated.
Thanks!
Firstly, why are you using HTMLBody property instead of the plain text Body?
Secondly, you can use MailItem.SaveAs(..., olTxt) to save the message as a text file. Or do you mean something else by txt file?
The security prompt is raised by Outlook if your antivirus app is not up to date. If you cannot control the environment where your code runs, Extended MAPI (C++ or Delphi only) or a wrapper like Redemption (any language - I am its author) are pretty much your only option. See http://www.outlookcode.com/article.aspx?id=52 for more details.
In Redemption, you can have something like the following:
using Redemption;
...
RDOSession session = new RDOSession();
RDOMail msg = session.GetMessageFromMsgFile(TheFileName);
msg.SaveAs(TxtFileName, rdoSaveAsType.olTXT);

Using MailKit, attachments with unicode file names appear as "untitled attachment" in Outlook

We are using MailKit in our application to send e-mails to users. These e-mails often have attachments with Unicode or long file names. Some e-mail clients, such as Outlook (when using POP or IMAP) or Outlook Express, cannot handle RFC 2231, and the result is that the attachments have names 'Untitled Attachment'.
Is there a way to send mails (using MailKit) supporting RFC 2047 (encoded-words) for attachments file names? A possible solution would be to keep RFC 2231 in filename in content-disposition, but use as a fall-back an encoded-word encoded name parameter in content-type. Is something like this supported?
I've just added support for using rfc2047 encoding to MimeKit.
There are now 2 ways of controlling the encoding method used for parameter values.
The first way is to set the encoding method on each individual Parameter:
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
The second way is to set the default parameter encoding method on the FormatOptions used for writing out the message and/or MIME part(s):
var options = FormatOptions.Default.Clone ();
options.ParameterEncodingMethod = ParameterEncodingMethod.Rfc2047;
message.WriteTo (options, stream);
I'll try to release a new MimeKit 1.3.0-beta3 to nuget soon with this feature.

Categories

Resources