Pergunta

É possível ler um arquivo .pst usando C#? Gostaria de fazer isso como um aplicativo independente, não como um adding do Outlook (se isso for possível).

Se já viu outro ASSIM perguntas semelhante a esta menção MailNavigator Mas estou procurando fazer isso programaticamente em C#.

Eu olhei para o Microsoft.Office.interop.outlook namespace, mas isso parece ser apenas para addins do Outlook. Libpst parece ser capaz de ler arquivos PST, mas isso está em C (desculpe Joel, eu não Aprenda C antes de se formar).

Qualquer ajuda seria muito apreciada, obrigado!

EDITAR:

Obrigado a todos pelas respostas! Aceitei a resposta de Matthew Ruston como resposta, porque ela me levou ao código que eu estava procurando. Aqui está um exemplo simples do que eu consegui funcionar (você precisará adicionar uma referência ao 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;
        }
    }
}

Observação: Este código pressupõe que o Outlook esteja instalado e já configurado para o usuário atual. Ele usa o perfil padrão (você pode editar o perfil padrão indo para o e -mail no painel de controle). Uma grande melhoria nesse código seria criar um perfil temporário a ser usado em vez do padrão e depois destruí -lo uma vez concluído.

Foi útil?

Solução

A biblioteca do Outlook Interop não é apenas para Addins. Por exemplo, ele pode ser usado para escrever um aplicativo de console que apenas lê todos os contatos do seu Outlook. Tenho certeza de que a Biblioteca Interop padrão do Microsoft Outlook permitirá que você leia o e -mail - embora provavelmente lançará um prompt de segurança no Outlook de que o usuário terá que clicar.

EDITAR% S: Na verdade, implementar a leitura de correio usando o Outlook Interop depende do que sua definição de 'independente' significa. A interop inteiro do Outlook exige que o Outlook seja instalado na máquina cliente para funcionar.

// 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();
    }
}
}

Outras dicas

Eu passei e fiz a refatoração de subpastas

    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);
        }
    }

Como já mencionado em uma de suas perguntas vinculadas, eu também recomendo usar o Redenção biblioteca. Estou usando -o em um aplicativo comercial para processar e -mails do Outlook e executar várias tarefas com eles. Está funcionando perfeitamente e impede que apareça os alertas de segurança irritantes. Isso significaria usar o COM Interop, mas isso não deve ser um problema.

Há uma biblioteca nesse pacote chamado RDO, que está substituindo o CDO 1.21, que permite acessar os arquivos PST diretamente. Então é tão fácil quanto escrever (código 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

Você pode usar PSTSDK.NET: .NET PORTO DO FORMATO DE ARQUIVO PST SDK Biblioteca que é de código aberto para ler o arquivo PST sem Outlook instalado.

Para aqueles que mencionam que eles não vêem a coleção de lojas:

A coleção de lojas foi adicionada no Outlook 2007. Portanto, se você estiver usando uma biblioteca de interop criada a partir de uma versão anterior (em uma tentativa de ser independente da versão - isso é ver comum), então seria por isso que você não verá as lojas coleção.

Suas únicas opções para obter as lojas são fazer um dos seguintes:

  • Use uma biblioteca de interop para o Outlook 2007 (isso significa que seu código não funcionará para versões anteriores do Outlook).
  • Enumere todas as pastas de nível superior com o modelo de objeto Outlook, extraia o armazenamento de cada pasta e use interfaces CDO ou MAPI para obter mais informações sobre cada loja.
  • Enumere a coleção InfoStorres do objeto de sessão CDO e use a coleção Fields de objeto InfoStore para obter mais informações sobre cada loja.
  • Ou (a maneira mais difícil) Use a chamada MAPI estendida (em C ++): imapisession :: getmsgStorestable.

Outra solução opcional: NetpStextractor

Esta é uma API .NET para ler o arquivo PST Outlook sem Outlook instalado.

Você pode encontrar a versão demo aqui.

Vamos usar isso, para fornecer uma solução que não depende do Outlook.

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

É muito caro, mas esperamos que reduza o tempo de desenvolvimento e aumente a qualidade.

A API MAPI é o que você está procurando. Infelizmente, ele não está disponível no .NET, por isso tenho medo que você tenha que recorrer a um código não gerenciado.

Um rápido Google revela vários invólucros disponíveis, talvez eles funcionem para você?

Isso também pode ser útil: http://www.wischik.com/lu/programmer/mapi_utils.html

este O conector do .NET para o Outlook pode começar.

Sim, com o IndependentEntSoft PST .NET é possível ler/exportar o arquivo .pst protegido por senha protegida e criptografada.

Encontrei alguns recursos diretamente da Microsoft, que podem ser úteis para concluir esta tarefa. UMA Pesquise no MSDN revela o seguinte.

Observe que quando você está adicionando uma referência ao microsoft.office.interop.outlook, a documentação insiste que você o faça através da guia .NET em vez da guia COM.

Código realmente útil. Se você tiver PST e armazenar suas mensagens na raiz (sem nenhum diretório), poderá usar o seguinte no método 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);
      }
 }

Sim, você pode usar o MS Access e, em seguida, importar seu conteúdo PST ou apenas vinculá -lo (lento!).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top