.net 如何在C#中使用Outlook MAPI打开.eml文件?

dy1byipe  于 2022-12-27  发布在  .NET
关注(0)|答案(5)|浏览(276)

我有一个C#应用程序,读取.msg文件并提取正文和附件。但是,当我尝试加载.eml文件时,应用程序崩溃。

MailItem mailItem = (MailItem)outlookApp.CreateItemFromTemplate(msgFileName);
mailItem.SaveAs(fullFilename, OlSaveAsType.olHTML); // save body in html format
for(int i = 0; i < mailItem.Attachments.Count; i++)
    mailItem.Attachments[i].SaveAsFile(filename); // save attachments

这适用于.msg文件,但不适用于.eml文件。我不明白为什么.eml文件不工作,因为我可以在Outlook 2010中打开.eml文件。
如何使用Outlook Primary Interop Assembly加载.eml文件?

exdqitrt

exdqitrt2#

CreateItemFromTemplate只适用于MSG/OFT文件。对于EML文件,您需要在代码中显式解析该文件或使用第三方库(如Redemption - I am its author):
以下代码将创建一个MSG文件,并使用RedemptionRDOSession对象)将一个EML文件导入其中:

set Session = CreateObject("Redemption.RDOSession")
  Session.MAPIOBJECT = outlookApp.Session.MAPIOBJECT
  set Msg = Session.CreateMessageFromMsgFile("C:\Temp\temp.msg")
  Msg.Import "C:\Temp\test.eml", 1024
  Msg.Save
  MsgBox Msg.Subject

然后,您可以使用邮件(RDOMail)访问它的各种属性(主题、正文等)

ulydmbyx

ulydmbyx3#

为了从.eml文件创建MailItem,您可以使用以下两个步骤:首先打开一个Outlook进程示例,然后使用Outlook API创建MailItem。

string file = @"C:\TestEML\EmlMail.eml";
  System.Diagnostics.Process.Start(file);
  Outlook.Application POfficeApp = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");  // note that it returns an exception if Outlook is not running
  Outlook.MailItem POfficeItem = (Outlook.MailItem)POfficeApp.ActiveInspector().CurrentItem; // now pOfficeItem is the COM object that represents your .eml file
70gysomp

70gysomp4#

虽然Outlook可以打开EML文件,有没有办法做到这一点编程只与VBA。所以我创建了这个VBA宏循环通过一些文件夹,并打开每个EML文件使用***SHELL EXEC***。它可能需要几毫秒,直到Outlook打开EML文件,所以VBA等待,直到在ActiveInspector中打开的东西。最后,这封电子邮件被复制到一些选定的文件夹,并且(在成功的情况下)删除原始EML文件。
在这里查看我的完整答案(和代码):https://stackoverflow.com/a/33761441/3606250

l3zydbqr

l3zydbqr5#

假设已安装outlook...
仅对于msg文件,当outlook正在运行/已打开时,您可以使用OpenSharedItem

Microsoft.Office.Interop.Outlook.Application appOutlook = new Microsoft.Office.Interop.Outlook.Application();
var myMailItem = appOutlook.Session.OpenSharedItem(strPathToSavedEmailFile) as Microsoft.Office.Interop.Outlook.MailItem;

对于eml文件或msg文件(Outlook将打开并弹出):

var strPathToSavedEmailFile=@"C:\temp\mail.eml";
//Microsoft.Win32 namespace to get path from registry
var strPathToOutlook=Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\App Paths\outlook.exe").GetValue("").ToString();
//var strPathToOutlook=@"C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE";

string strOutlookArgs;
if(Path.GetExtension(strPathToSavedEmailFile)==".eml")
{
  strOutlookArgs =  @"/eml "+strPathToSavedEmailFile;  // eml is an undocumented outlook switch to open .eml files
}else
    {
     strOutlookArgs =   @"/f "+strPathToSavedEmailFile;
    }

Process p = new System.Diagnostics.Process();
p.StartInfo = new ProcessStartInfo()
{
    CreateNoWindow = false,
    FileName = strPathToOutlook, 
    Arguments = strOutlookArgs
};
p.Start();

//Wait for Outlook to open the file
Task.Delay(TimeSpan.FromSeconds(5)).GetAwaiter().GetResult();

Microsoft.Office.Interop.Outlook.Application appOutlook = new Microsoft.Office.Interop.Outlook.Application();
//Microsoft.Office.Interop.Outlook.MailItem myMailItem  = (Microsoft.Office.Interop.Outlook.MailItem)appOutlook.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
var myMailItem = (Microsoft.Office.Interop.Outlook.MailItem)appOutlook.ActiveInspector().CurrentItem;

//Get the Email Address of the Sender from the Mailitem 
string strSenderEmail=string.Empty;
if(myMailItem.SenderEmailType == "EX"){
    strSenderEmail=myMailItem.Sender.GetExchangeUser().PrimarySmtpAddress;
}else{
    strSenderEmail=myMailItem.SenderEmailAddress;
}

//Get the Email Addresses of the To, CC, and BCC recipients from the Mailitem   
var strToAddresses = string.Empty;
var strCcAddresses= string.Empty;
var strBccAddresses = string.Empty;
foreach(Microsoft.Office.Interop.Outlook.Recipient recip in myMailItem.Recipients)
    {
    const string PR_SMTP_ADDRESS = @"http://schemas.microsoft.com/mapi/proptag/0x39FE001E";
    Microsoft.Office.Interop.Outlook.PropertyAccessor pa = recip.PropertyAccessor; 
    string eAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString(); 
    if(recip.Type ==1)
        {
        if(strToAddresses == string.Empty)
            {
            strToAddresses = eAddress;
            }else
                {
                strToAddresses = strToAddresses +","+eAddress;
                }
        };
    if(recip.Type ==2)
        {
        if(strCcAddresses == string.Empty)
            {
            strCcAddresses = eAddress;
            }else
                {
                strCcAddresses = strCcAddresses +","+eAddress;
                }       
        };
    if(recip.Type ==3)
        {
        if(strBccAddresses == string.Empty)
            {
            strBccAddresses = eAddress;
            }else
                {
                strBccAddresses = strBccAddresses +","+eAddress;
                }       
        };
    }
Console.WriteLine(strToAddresses);
Console.WriteLine(strCcAddresses);
Console.WriteLine(strBccAddresses);
foreach(Microsoft.Office.Interop.Outlook.Attachment mailAttachment in myMailItem.Attachments){
    Console.WriteLine(mailAttachment.FileName);
}
Console.WriteLine(myMailItem.Subject);
Console.WriteLine(myMailItem.Body);

相关问题