JimDel
JimDel

Reputation: 4359

Need help / advice on how to get attachments out of a MIME file using C#

I have files that are in a MIME format. I need to save out the attachments in those files. Email isn't involved. I can find a lot of examples on how to add attachments to emails or MIME files but very little on how to get them out. I've looked at several MIME parsers like LimiLabs and one from SASA. But they don't show samples for what I'm looking for. And I'm too much of a beginner to make sense of them from what little documentation they have. So, is this even possible? Do I need to use 3rd party items or can it be done with just .NET?

MIME-Version: 1.0
Content-Type: multipart/related;boundary="IGi2rPe3RHug37'6b21FU)yg.3tkE/l5r0e-l+ZXD8qh,-P:"

--IGi2rPe3RHug37'6b21FU)yg.3tkE/l5r0e-l+ZXD8qh,-P:
Content-type: text/xml; charset="UTF-8"
Content-id: ACCOUNT

<?xml version="1.0" encoding="utf-8"?>
<ACCOUNT>
    <CustId>
       <CustPermId>ivan</CustPermId>
       <CustLoginId>smaher</CustLoginId>
    </CustId>
</ACCOUNT>

--IGi2rPe3RHug37'6b21FU)yg.3tkE/l5r0e-l+ZXD8qh,-P:
Content-type: image/jpeg
Content-id: CLOCK.JPG
Content-description: Notice of Cancellation


[Base64 Encoded Data Here]
--IGi2rPe3RHug37'6b21FU)yg.3tkE/l5r0e-l+ZXD8qh,-P:--

Upvotes: 0

Views: 1186

Answers (1)

PeterK
PeterK

Reputation: 3817

I'm not aware of any built-in MIME parsers in the .NET Framework, you'll have to work either with third-party components or use CDOSYS (Microsoft CDO for Windows 2000). This latter is a COM component shipped with any Windows version newer than Windows 2000. It's an old thing and so relying on it isn't exactly future-proof, but it's available today and it works.

To use CDOSYS, just add a COM reference to this library and ADODB and use the following code to load and parse an email:

CDO.Message msg = new CDO.Message();

// load MIME into CDO
using (FileStream stream = new FileStream(emailFileSpec, FileMode.Open))
{
    // read file into a byte stream
    byte[] emailData = new byte[stream.Length];
    stream.Read(emailData, 0, (int)stream.Length);

    // load byte stream data into an ADODB stream for CDO
    ADODB.Stream stm = new ADODB.Stream();
    stm.Open(
        System.Reflection.Missing.Value,
        ADODB.ConnectModeEnum.adModeUnknown,
        ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified,
        null, null);
    stm.Type = ADODB.StreamTypeEnum.adTypeBinary;
    stm.Write(emailData);
    stm.Flush();
    stm.SetEOS();

    // attach data source to the CDO object
    msg.DataSource.OpenObject(stm, "_Stream");
    stm.Close();
}

This is just an example, the code can be simplified with File.ReadAllBytes().

Once you have the email loaded, you can access attachments via the Attachment property of the IMessage interface (i.e. CDO.Message). Each attachment is an object that implements the IBodyPart interface. Use the GetDecodedContentStream() method to load the decoded contents into an ADODB.Stream, which you can read into a .NET byte array. Example:

// get decoded data into an ADODB stream
ADODB.Stream stm = part.GetDecodedContentStream();

// cast to COM IStream and load into byte array
IStream comStream = (IStream)stm;
byte[] attachmentData = new byte[stm.Size];
comStream.Read(attachmentData, stm.Size, IntPtr.Zero);

HTH.

Upvotes: 1

Related Questions