是否可以使用C#读取.PST文件?我想将此作为一个独立的应用程序,而不是作为Outlook插件(如果可能的话).
如果已经看到类似于提及MailNavigator的其他 SO 问题 ,但我希望在C#中以编程方式执行此操作.
我查看了Microsoft.Office.Interop.Outlook命名空间,但它似乎只适用于Outlook插件.LibPST似乎能够读取PST文件,但这是在C中(对不起Joel,我毕业前没有学过C).
任何帮助将不胜感激,谢谢!
编辑:
谢谢大家的回复!我接受了Matthew Ruston的回答作为答案,因为它最终导致我找到了我正在寻找的代码.这是我工作的一个简单示例(您需要添加对Microsoft.Office.Interop.Outlook的引用):
using System; using System.Collections.Generic; using Microsoft.Office.Interop.Outlook; namespace PSTReader { class Program { static void Main () { try { IEnumerablemailItems = readPst(@"C:\temp\PST\Test.pst", "Test PST"); foreach (MailItem mailItem in mailItems) { Console.WriteLine(mailItem.SenderName + " - " + mailItem.Subject); } } catch (System.Exception ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } private static IEnumerable readPst(string pstFilePath, string pstName) { List mailItems = new List (); Application app = new Application(); NameSpace outlookNs = app.GetNamespace("MAPI"); // Add PST file (Outlook Data File) to Default Profile outlookNs.AddStore(pstFilePath); MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder(); // Traverse through all folders in the PST file // TODO: This is not recursive, refactor Folders subFolders = rootFolder.Folders; foreach (Folder folder in subFolders) { Items items = folder.Items; foreach (object item in items) { if (item is MailItem) { MailItem mailItem = item as MailItem; mailItems.Add(mailItem); } } } // Remove PST file from Default Profile outlookNs.RemoveStore(rootFolder); return mailItems; } } }
注意:此代码假定已安装Outlook并已为当前用户配置.它使用默认配置文件(您可以通过转到控制面板中的Mail来编辑默认配置文件).对此代码的一个主要改进是创建一个临时配置文件而不是默认配置文件,然后在完成后将其销毁.
Outlook Interop库不仅适用于插件.例如,它可用于编写只读取所有Outlook联系人的控制台应用程序.我很确定标准的Microsoft Outlook Interop库可以让你阅读邮件 - 尽管它可能会在Outlook中抛出一个用户必须点击的安全提示.
编辑:实际上使用Outlook Interop实现邮件阅读取决于您对"独立"的定义.Outlook Interop lib要求在客户端计算机上安装Outlook才能运行.
// Dumps all email in Outlook to console window. // Prompts user with warning that an application is attempting to read Outlook data. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Outlook = Microsoft.Office.Interop.Outlook; namespace OutlookEmail { class Program { static void Main(string[] args) { Outlook.Application app = new Outlook.Application(); Outlook.NameSpace outlookNs = app.GetNamespace("MAPI"); Outlook.MAPIFolder emailFolder = outlookNs.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox); foreach (Outlook.MailItem item in emailFolder.Items) { Console.WriteLine(item.SenderEmailAddress + " " + item.Subject + "\n" + item.Body); } Console.ReadKey(); } } }
正如您在一个链接的SO问题中已经提到的,我还建议使用Redemption库.我在商业应用程序中使用它来处理Outlook邮件并使用它们执行各种任务.它运行完美,可以防止出现恼人的安全警报.这意味着使用COM Interop,但这应该不是问题.
该软件包中有一个名为RDO的库,它正在替换CDO 1.21,它允许您直接访问PST文件.然后它就像写(VB6代码)一样简单:
set Session = CreateObject("Redemption.RDOSession") 'open or create a PST store set Store = Session.LogonPstStore("c:\temp\test.pst") set Inbox = Store.GetDefaultFolder(6) 'olFolderInbox MsgBox Inbox.Items.Count
我经历了对子文件夹的重构
private static IEnumerablereadPst(string pstFilePath, string pstName) { List mailItems = new List (); Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application(); NameSpace outlookNs = app.GetNamespace("MAPI"); // Add PST file (Outlook Data File) to Default Profile outlookNs.AddStore(pstFilePath); string storeInfo = null; foreach (Store store in outlookNs.Stores) { storeInfo = store.DisplayName; storeInfo = store.FilePath; storeInfo = store.StoreID; } MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder(); // Traverse through all folders in the PST file Folders subFolders = rootFolder.Folders; foreach (Folder folder in subFolders) { ExtractItems(mailItems, folder); } // Remove PST file from Default Profile outlookNs.RemoveStore(rootFolder); return mailItems; } private static void ExtractItems(List mailItems, Folder folder) { Items items = folder.Items; int itemcount = items.Count; foreach (object item in items) { if (item is MailItem) { MailItem mailItem = item as MailItem; mailItems.Add(mailItem); } } foreach (Folder subfolder in folder.Folders) { ExtractItems(mailItems, subfolder); } }