【问题标题】:Save Mail in MIME format (*.eml) in Outlook Add-In在 Outlook 加载项中以 MIME 格式 (*.eml) 保存邮件
【发布时间】:2014-10-12 10:00:13
【问题描述】:

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

我读过一些关于 Outlook WebServices 的文章。也许我可以在交换服务器中搜索当前在 Outlook 中选择的邮件,然后从交换中再次接收并将其保存为 .eml?这个选项我需要什么?

是否可以以简单的方式将保存的 .msg 转换为 .eml(保留所有详细信息、标题等)?

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

【问题讨论】:

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


    【解决方案1】:

    你可以

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

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

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

      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
    

    【讨论】:

    • 感谢您的回答。我尝试手动“转换”消息,但转换所有消息(所有标题等)似乎非常困难。我不想使用外部库。而且我不想花太多时间在这上面,所以我不想用 C++ 编写自己的转换器。所以我最终决定使用 MailItem.SaveAs() 方法提供的 .msg 格式。我们可以忍受。
    【解决方案2】:

    这是 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

    【讨论】:

    • 谢谢!!!我已经尝试解决这个问题很长时间了!而且它比 Redemption.RDOSession 效果好很多。
    猜你喜欢
    • 2021-06-13
    • 2011-07-28
    • 1970-01-01
    • 2020-04-15
    • 2019-06-21
    • 2012-06-13
    • 1970-01-01
    • 2019-02-10
    • 2013-01-06
    相关资源
    最近更新 更多