我有一个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 主互操作程序集加载 .eml 文件?
尝试此示例代码 轻松从 检索电子邮件信息。电子移动单元文件
CreateItemFromTemplate
仅适用于MSG/OFT文件。对于 EML 文件,您需要在代码中显式解析该文件或使用第三方库(例如 Redemption - 我是它的作者):
以下代码将创建一个 MSG 文件,并使用 Redemption(RDOSession 对象)将 EML 文件导入其中:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = outlookApp.Session.MAPIOBJECT
set Msg = Session.CreateMessageFromMsgFile("C:Temptemp.msg")
Msg.Import "C:Temptest.eml", 1024
Msg.Save
MsgBox Msg.Subject
然后,您可以使用消息 (RDOMail) 访问它的各种属性(主题、正文等)。
为了从.eml文件创建MailItem,您可以使用以下两个步骤:首先打开Outlook流程实例,然后使用Outlook API创建MailItem。
string file = @"C:TestEMLEmlMail.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
尽管Outlook可以打开EML文件,但仅使用VBA无法以编程方式执行此操作。所以我创建了这个VBA宏,它循环访问某个文件夹并使用SHELL EXEC打开每个EML文件。Outlook 打开 EML 文件可能需要几毫秒,因此 VBA 会等到在 ActiveInspector 中打开某些内容。最后,此电子邮件被复制到某个选定的文件夹中,并且(如果成功)原始EML文件将被删除。
在这里查看我的完整答案(和代码):https://stackoverflow.com/a/33761441/3606250
假设安装了 outlook...
仅对于消息文件,当 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:tempmail.eml";
//Microsoft.Win32 namespace to get path from registry
var strPathToOutlook=Registry.LocalMachine.OpenSubKey(@"SoftwareMicrosoftWindowsCurrentVersionApp Pathsoutlook.exe").GetValue("").ToString();
//var strPathToOutlook=@"C:Program FilesMicrosoft OfficerootOffice16OUTLOOK.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);