在Outlook加载项中以MIME格式(* .eml)保存邮件

时间:2014-08-19 10:27:16

标签: c# .net email outlook add-in

我想编写一个小的Outlook插件(C#),它以纯MIME格式(.eml)将选定的邮件(MailItem)保存到磁盘。 MailItem.SaveAs()方法仅允许以.msg格式保存。 有没有其他(简单)方法,以eml格式保存邮件?我想保留原始邮件的所有细节。

我已经阅读了有关Outlook WebServices的内容。也许我可以在交换服务器中搜索当前在Outlook中选择的邮件并从交换机再次接收并将其保存为.eml?该选项需要什么?

是否可以轻松地将保存的.msg转换为.eml(保留所有详细信息,标题等)?

我希望有人可以帮我解决这个问题,因为我花了几个小时寻找没有任何结果的解决方案。

2 个答案:

答案 0 :(得分:2)

你可以

1)一次在代码中显式创建MIME文件。您也可以使用现有的MIME转换器(我过去使用Lumisoft) - 但它们不会在一次调用中转换Outlook消息;您将需要expliiclty构建所有标头和MIME部分。

2)使用IConverterSession对象(仅限C ++或Delphi) - 这与Outlook使用的MIME转换器相同。您可以在OutlookSpy中使用它(单击IConverterSession按钮)。以下脚本(VBS)将Outlook中当前选定的邮件另存为EML文件

3)使用Redemption及其RDOMail .SaveAs或SafeMailItem。另存为方法 - 它可以保存为MIME格式(olRfc822)以及十几种其他格式。它在可用时使用IConverterSession对象(Outlook 2003及更高版本),或者在旧版本的Outlook中使用自己的转换器,或者在使用MAP版的Exchange版本时使用它。

  set Session = CreateObject("Redemption.RDOSession")
  Session.MAPIOBJECT = Application.Session.MAPIOBJECT
  set rItem = Session.GetMessageFromID(Application.ActiveExplorer.Selection(1).EntryID)
  rItem.SaveAs "c:\temp\test.eml", 1024

答案 1 :(得分:1)

这是C#的IConvertSession代理:

using Microsoft.Office.Interop.Outlook;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace Exchange.Export.MAPIMessageConverter
{
    internal class MAPIMethods
    {
        [Flags]
        public enum MAPITOMIMEFLAGS
        {
            CCSF_SMTP = 0x0002,
            CCSF_NOHEADERS = 0x0004,
            CCSF_USE_TNEF = 0x0010,
            CCSF_INCLUDE_BCC = 0x0020,
            CCSF_8BITHEADERS = 0x0040,
            CCSF_USE_RTF = 0x0080,
            CCSF_PLAIN_TEXT_ONLY = 0x1000,
            CCSF_NO_MSGID = 0x4000,
        }

        [Flags]
        public enum CLSCTX
        {
            CLSCTX_INPROC_SERVER = 0x1,
            CLSCTX_INPROC_HANDLER = 0x2,
            CLSCTX_LOCAL_SERVER = 0x4,
            CLSCTX_REMOTE_SERVER = 0x10,
            CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
            CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
            CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
        }


        public static Guid CLSID_IConverterSession = new Guid("{4e3a7680-b77a-11d0-9da5-00c04fd65685}");

        public static Guid IID_IConverterSession = new Guid("{4b401570-b77b-11d0-9da5-00c04fd65685}");

        public enum ENCODINGTYPE
        {
            IET_BINARY = 0,
            IET_BASE64 = 1,
            IET_UUENCODE = 2,
            IET_QP = 3,
            IET_7BIT = 4,
            IET_8BIT = 5,
            IET_INETCSET = 6,
            IET_UNICODE = 7,
            IET_RFC1522 = 8,
            IET_ENCODED = 9,
            IET_CURRENT = 10,
            IET_UNKNOWN = 11,
            IET_BINHEX40 = 12,
            IET_LAST = 13
        }

        public enum MIMESAVETYPE
        {
            SAVE_RFC822 = 0,
            SAVE_RFC1521 = 1
        }

        [ComVisible(false)]
        [ComImport()]
        [Guid("00020307-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IMessage
        {
        }

        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("4b401570-b77b-11d0-9da5-00c04fd65685")]
        public interface IConverterSession
        {
            [PreserveSig]
            int Placeholder0();

            [PreserveSig]
            uint SetEncoding(
            [In, MarshalAs(UnmanagedType.I4)] ENCODINGTYPE DispId
            );

            [PreserveSig]
            int Placeholder1();

            [PreserveSig]
            uint MIMEToMAPI(
                [In, MarshalAs(UnmanagedType.Interface)]
                Stream pstm,
                [Out, MarshalAs(UnmanagedType.Interface)]
                MailItem pmsg,
                object pszSrcSrv,
                uint ulFlags
            );

            [PreserveSig]
            uint MAPIToMIMEStm(
                [In, MarshalAs(UnmanagedType.Interface)]
                IMessage pmsg,
                [Out, MarshalAs(UnmanagedType.Interface)]
                IStream pstm,
                MAPITOMIMEFLAGS ulFlags
            );

            [PreserveSig]
            int Placeholder2();

            [PreserveSig]
            int Placeholder3();

            [PreserveSig]
            int Placeholder4();

            [PreserveSig]
            int SetTextWrapping(
                bool fWrapText,
                uint ulWrapWidth
            );

            [PreserveSig]
            uint SetSaveFormat(
                [In, MarshalAs(UnmanagedType.I4)]
                MIMESAVETYPE mstSaveFormat
            );

            [PreserveSig]
            int Placeholder5();

            [PreserveSig]
            int Placeholder6();
        }
    }
}

使用它:

private Stream GetEmlStream(Outlook.MailItem mail)
{
    Type converter = Type.GetTypeFromCLSID(MAPIMethods.CLSID_IConverterSession);
    object obj = Activator.CreateInstance(converter);
    MAPIMethods.IConverterSession session = (MAPIMethods.IConverterSession)obj;

    if (session != null)
    {
        uint hr = session.SetEncoding(MAPIMethods.ENCODINGTYPE.IET_QP);
        hr = session.SetSaveFormat(MAPIMethods.MIMESAVETYPE.SAVE_RFC822);
        var stream = new ComMemoryStream();
        hr = session.MAPIToMIMEStm((MAPIMethods.IMessage)mail.MAPIOBJECT, stream, MAPIMethods.MAPITOMIMEFLAGS.CCSF_SMTP);
        if (hr != 0)
            throw new ArgumentException(There are some invalid COM arguments");

        stream.Position = 0;

        return stream;
    }

    return null;
}

ComMemoryStream:https://stackoverflow.com/a/6602066/2532356

其他字体:

http://www.pcreview.co.uk/threads/iconvertersession-in-c.3716714/

http://www.microsoft-questions.com/microsoft/Plaform-SDK-Mapi/31018989/mimetomapi-and-mapitomimestm-method-take-a-pointer-to-an-imessage-extended.aspx