我可以用 C# 读取 Outlook (2003/2007) PST 文件吗?
-
06-09-2019 - |
题
是否可以使用 C# 读取 .PST 文件?我想将其作为独立的应用程序来执行,而不是作为 Outlook 插件(如果可能的话)。
如果见过 其他 所以 问题 相似的 提到这一点 邮件导航器 但我希望在 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 {
IEnumerable<MailItem> mailItems = 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<MailItem> readPst(string pstFilePath, string pstName) {
List<MailItem> mailItems = new List<MailItem>();
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 已安装并已为当前用户配置。它使用默认配置文件(您可以通过转到控制面板中的邮件来编辑默认配置文件)。此代码的一项重大改进是创建一个临时配置文件来代替默认配置文件,然后在完成后将其销毁。
解决方案
观互操作库不仅是加载项。例如,它可以用来写一个控制台应用程序,仅仅读您的所有Outlook联系人。我敢肯定的是,标准的Microsoft Outlook互操作库将让你读的邮件 - 尽管它可能会在Outlook中引发安全提示,用户必须通过点击
EDITS :实际执行使用Outlook互操作的邮件阅读取决于你的“独立”的定义是指。观互操作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();
}
}
}
其他提示
我经历,也做了重构子文件夹
private static IEnumerable<MailItem> readPst(string pstFilePath, string pstName)
{
List<MailItem> mailItems = new List<MailItem>();
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<MailItem> 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);
}
}
根据您的SO联的一个问题已经提到的,我也建议使用赎回库。我在处理Outlook中的邮件,并与他们进行各种任务的商业应用使用它。它的工作完美无瑕,并防止显示出来烦人的安全警报。这将意味着使用COM互操作,但是这不应该是一个问题。
有在该包称为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
您可以使用 pstsdk.net:PST文件格式SDK的.NET端口库,它是开源读pst文件的没有强>安装Outlook。
对于那些提到他们看不到 Stores 集合的人:
Outlook 2007 中添加了 Stores 集合。因此,如果您使用的是从早期版本创建的互操作库(试图与版本无关 - 这很常见),那么这就是您看不到 Stores 集合的原因。
您获得商店的唯一选择是执行以下操作之一:
- 使用 Outlook 2007 的互操作库(这意味着您的代码不适用于早期版本的 Outlook)。
- 使用 Outlook 对象模型枚举所有顶级文件夹,提取每个文件夹的 StoreID,然后使用 CDO 或 MAPI 接口获取有关每个商店的更多信息。
- 枚举 CDO 会话对象的 InfoStores 集合,然后使用 InfoStore 对象的 fields 集合来获取有关每个商店的更多信息。
- 或者(最难的方法)使用扩展 MAPI 调用(在 C++ 中):IMAPISession::GetMsgStoresTable。
我们要利用这一点,来提供一个不依赖于前景的解决方案。
http://www.independentsoft.de/pst/index.html
这是非常昂贵的,但我们希望,这将降低开发时间,提高质量。
在MAPI API是你在找什么。不幸的是它不是在.NET中可用,所以我怕你会不得不求助于调用非托管代码。
一个快速谷歌揭示了几个可用的包装,也许他们为你工作?
这也可能会有所帮助: http://www.wischik.com/lu /programmer/mapi_utils.html
的Outlook这 .NET连接器可以让你开始。
是,与Independentsoft PST .NET能够读/出口密码保护和加密的pst文件。
我直接从 Microsoft 找到了一些资源,可能有助于完成此任务。A 在 MSDN 上搜索 揭示了以下内容。
请注意,当您添加对 Microsoft.Office.Interop.Outlook 的引用时, 文档 坚持您通过 .NET 选项卡而不是 COM 选项卡来执行此操作。
真的有用的代码。如果已在其根部PST和存储邮件(没有任何目录),那么可以使用在方法readPst以下内容:
MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder();
Items items = rootFolder.Items;
foreach (object item in items)
{
if (item is MailItem)
{
MailItem mailItem = item as MailItem;
mailItems.Add(mailItem);
}
}
是的,你可以使用MS Access,然后你要么导入您的PST内容或只是链接它(慢!)。