Вопрос

Можно ли прочитать файл .PST с помощью C#?Я хотел бы сделать это как отдельное приложение, а не как надстройку Outlook (если это возможно).

Если бы видели другой ТАК вопросы похожий к этому упоминанию Почтовый Навигатор но я хочу сделать это программно на С#.

Я посмотрел на Microsoft.Office.Interop.Outlook пространство имен, но, похоже, оно предназначено только для надстроек Outlook. LibPST кажется, может читать файлы PST, но это на C (извини, Джоэл, я не выучить C до окончания учебы).

Любая помощь будет принята с благодарностью, спасибо!

РЕДАКТИРОВАТЬ:

Спасибо всем за ответы!Я принял ответ Мэтью Растона как ответ, потому что он в конечном итоге привел меня к коду, который я искал.Вот простой пример того, что мне нужно для работы (вам нужно будет добавить ссылку на 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 Interop предназначена не только для надстроек.Например, его можно использовать для написания консольного приложения, которое просто читает все ваши контакты Outlook.Я почти уверен, что стандартная библиотека Microsoft Outlook Interop позволит вам прочитать почту, хотя она, вероятно, выдаст запрос безопасности в Outlook, по которому пользователю придется щелкнуть мышью.

РЕДАКТИРОВАНИЕ:Реальная реализация чтения почты с помощью Outlook Interop зависит от того, что означает ваше определение «автономного».Для работы библиотеки Outlook Interop требуется, чтобы 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 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

Вы можете использовать pstsdk.net:.NET-порт SDK формата файла PST библиотека с открытым исходным кодом для чтения PST-файла без Outlook установлен.

Для тех, кто упоминает, что не видит коллекцию «Магазины»:

Коллекция Stores была добавлена ​​в Outlook 2007.Итак, если вы используете библиотеку взаимодействия, созданную на основе более ранней версии (в попытке быть независимой от версии - это очень распространено), то именно поэтому вы не увидите коллекцию Stores.

Единственный способ получить Магазины — это выполнить одно из следующих действий:

  • Используйте библиотеку взаимодействия для Outlook 2007 (это означает, что ваш код не будет работать в более ранних версиях Outlook).
  • Перечислите все папки верхнего уровня с помощью объектной модели Outlook, извлеките StoreID каждой папки, а затем используйте интерфейсы CDO или MAPI, чтобы получить дополнительные сведения о каждом магазине.
  • Перечислите коллекцию InfoStore объекта сеанса CDO, а затем используйте коллекцию полей объекта InfoStore, чтобы получить дополнительную информацию о каждом магазине.
  • Или (самый сложный способ) используйте расширенный вызов MAPI (на C++):IMAPISession::GetMsgStoresTable.

Еще одно опциональное решение: NetPstExtractor

Это API .Net для чтения PST-файла Outlook. без Outlook установлен.

Вы можете найти демо-версию здесь.

Мы собираемся использовать это, чтобы предоставить решение, которое не будет зависеть от перспектив.

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

Это очень дорого, но мы надеемся, что это сократит время разработки и повысит качество.

MAPI API — это то, что вам нужно.К сожалению, он недоступен в .Net, поэтому боюсь, вам придется прибегнуть к вызову неуправляемого кода.

Быстрый Google показывает несколько доступных оберток, может быть, они вам подойдут?

Это также может быть полезно: http://www.wischik.com/lu/programmer/mapi_utils.html

Этот Соединитель .NET для Outlook может помочь вам начать работу.

Да, с помощью Independentsoft PST .NET можно читать/экспортировать защищенный паролем и зашифрованный файл .pst.

Я нашел несколько ресурсов непосредственно от Microsoft, которые могут оказаться полезными для выполнения этой задачи.А поиск в 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, либо просто связать его (медленно!).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top