我可以在C#中阅读Outlook(2003/2007)PST文件吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以在C#中阅读Outlook(2003/2007)PST文件吗?相关的知识,希望对你有一定的参考价值。

是否可以使用C#读取.PST文件?我想将此作为一个独立的应用程序,而不是作为Outlook插件(如果可能的话)。

如果已经看到other SO questions similar提到MailNavigator但我希望在C#中以编程方式执行此操作。

我查看了Microsoft.Office.Interop.Outlook命名空间,但这似乎只适用于Outlook插件。 LibPST似乎能够读取PST文件,但这是在C(对不起乔尔,我没有learn C before graduating)。

任何帮助将不胜感激,谢谢!

编辑:

谢谢大家的回复!我接受了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:	empPSTTest.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并已为当前用户配置。它使用默认配置文件(您可以通过转到控制面板中的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 + "
" + item.Body);
        }
        Console.ReadKey();
    }
}
}
另一答案

是的,使用Independentsoft PST .NET可以读取/导出受密码保护和加密的.pst文件。

另一答案

我直接从Microsoft找到了一些资源,这可能有助于完成此任务。一个search on MSDN揭示了以下内容。

请注意,当您添加对Microsoft.Office.Interop.Outlook的引用时,the documentation坚持要求您通过.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内容或只链接它(慢!)。

另一答案

正如您在一个链接的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:	emp	est.pst")
set Inbox = Store.GetDefaultFolder(6) 'olFolderInbox
MsgBox Inbox.Items.Count
另一答案

我经历了对子文件夹的重构

    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);
        }
    }
另一答案

您可以使用开源的pstsdk.net: .NET port of PST File Format SDK库来读取未安装Outlook的pst文件。

另一答案

对于那些提到他们没有看到Stores系列的人:

Stores集合已添加到Outlook 2007中。因此,如果您正在使用从早期版本创建的互操作库(尝试独立于版本 - 这很常见),那么这就是您不会看到商店的原因采集。

您获得商店的唯一选择是执行以下操作之一:

  • 使用Outlook 2007的互操作库(这意味着您的代码不适用于早期版本的Outlook)。
  • 使用Outlook对象模型枚举所有顶级文件夹,提取每个文件夹的StoreID,然后使用CDO或MAPI接口获取有关每个商店的更多信息。
  • 枚举CDO会话对象的InfoStores集合,然后使用InfoStore对象的字段集合以获取有关每个商店的更多信息。
  • 或者(最难的方式)使用扩展MAPI调用(在C ++中):IMAPISession :: GetMsgStoresTable。
另一答案

另一个可选的解决方案:NetPstExtractor

这是一个.Net API,用于读取未安装Outlook的Outlook PST文件。

你可以找到演示版here.

另一答案

我们将使用它来提供不依赖于outlook的解决方案。

http://www.independentsoft.de/pst/index.html

它非常昂贵,但我们希望这会降低开发时间并提高质量。

另一答案

您正在寻找MAPI API。不幸的是它在.Net中不可用,所以我担心你不得不求助于调用非托管代码。

一个快速的谷歌揭示了几个可用的包装,也许它们适合你?

这可能也有帮助:http://www.wischik.com/lu/programmer/mapi_utils.html

另一答案

用于Outlook的This .NET连接器可能会帮助您入门。

以上是关于我可以在C#中阅读Outlook(2003/2007)PST文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

在共享文件夹中阅读 Outlook 电子邮件 - Python

Outlook 兑换 - 在阅读电子邮件时更改默认收件箱

Outlook 2013:添加按钮到阅读窗格?

Outlook VSTO附件在邮件主题中选择了文本和上下文菜单

阅读 ASP.NET 中的 Outlook 消息捕获越界错误

在JavaScript / JQuery中检索Outlook日历信息