2009-02-23 22 views
61

¿Es posible leer un archivo .PST usando C#? Me gustaría hacer esto como una aplicación independiente, no como un complemento de Outlook (si es posible).¿Puedo leer un archivo PST de Outlook (2003/2007) en C#?

Si han visto otherSOquestionssimilar a esta mención MailNavigator pero estoy en busca de hacer esto mediante programación en C#.

He consultado el espacio de nombres Microsoft.Office.Interop.Outlook pero parece ser solo para complementos de Outlook. LibPST parece ser capaz de leer archivos PST, pero esto está en C (lo siento Joel, no lo hice learn C before graduating).

¡Cualquier ayuda sería muy apreciada, gracias!

EDIT:

Gracias a todos por las respuestas! Acepté la respuesta de Matthew Ruston como la respuesta porque finalmente me llevó al código que estaba buscando. Aquí está un ejemplo sencillo de lo que tengo que trabajar (Usted tendrá que añadir una referencia a 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; 
     } 
    } 
} 

Nota: Este código se supone que Outlook está instalado y ya configurado para el usuario actual. Utiliza el Perfil predeterminado (puede editar el perfil predeterminado yendo a Correo en el Panel de control). Una mejora importante en este código sería crear un perfil temporal para usar en lugar del predeterminado, y luego destruirlo una vez que se haya completado.

+0

no tenía ni idea de que los AddStores y la lista de tiendas que existiera en la API de Outlook. ¡Buen post! –

+0

¿Me estoy perdiendo algo? ¿Por qué no puedo acceder a la colección Stores de outlookNS? No está en intellisense. –

+0

¿Incluyó 'using Microsoft.Office.Interop.Outlook;' en tu código? –

Respuesta

23

La biblioteca de Outlook de interoperabilidad no es sólo para los complementos. Por ejemplo, podría usarse para escribir una aplicación de consola que simplemente lea todos sus contactos de Outlook. Estoy bastante seguro de que la biblioteca estándar Interoperabilidad de Microsoft Outlook le permitirá leer el correo, aunque probablemente arrojará un mensaje de seguridad en Outlook que el usuario tendrá que hacer clic.

EDICIONES: En realidad, la implementación de la lectura de correo utilizando Outlook Interop depende de lo que signifique su definición de 'independiente'. Outlook Interop lib requiere que Outlook esté instalado en la 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(); 
    } 
} 
} 
+0

Es seguro asumir que Outlook se instalará en la máquina, sin embargo, preferiría que no fuera necesario tener Outlook abierto para leer desde el archivo PST. –

+0

No necesita estar abierto. La interop lib simplemente lo abre en segundo plano y lo cierra cuando haya terminado. –

+0

Ahhh, vale, eso suena bien. Veo algunos ejemplos de cómo usar esto para leer Contactos, pero estoy interesado en leer mensajes en un PST, no Contactos fuera de un servidor de Exchange. ¿Sabes, o tienes un ejemplo, sobre esto? –

0

MAPI API es lo que estás buscando. Desafortunadamente no está disponible en .Net así que me temo que tendrá que recurrir a llamar al código no administrado.

Un rápido Google revela varios contenedores disponibles, ¿quizás funcionan para usted?

Esto también podría ser útil: http://www.wischik.com/lu/programmer/mapi_utils.html

0

This conector .NET para Outlook podría empezar.

0

Sí, puede utilizar MS Access y luego importar su contenido pst o simplemente vincularlo (¡lento!).

+0

Lo siento, no veo cómo esto responde mi pregunta sobre cómo leer un archivo PST en C#. Explica más porfavor. –

+0

Oh, sí lo siento, olvidé la parte de C#, pero si tal vez puedes controlar el Acceso desde C#, aún puedes seguir por ese camino. ¡No probado! – Lorenzo

6

Como ya mencioné en una de sus preguntas SO vinculadas, también recomendaría usar la biblioteca Redemption. Lo estoy usando en una aplicación comercial para procesar correos de Outlook y realizar varias tareas con ellos. Funciona perfectamente y evita que aparezcan las molestas alertas de seguridad. Significaría usar COM Interop, pero eso no debería ser un problema.

Hay una biblioteca en ese paquete llamada RDO que reemplaza al CDO 1.21, que le permite acceder a los archivos PST directamente. Entonces es tan fácil como escribir (código de Visual Basic 6):

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 
5

que pasé y hice la refactorización para las subcarpetas

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

¿Qué es pstName? Ya pasaste el pstFilePath en él, ¿por qué necesitas pstName? – HoKy22

0

Vamos a usar esto, para proporcionar una solución que no se basa en perspectiva

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

es muy caro, pero esperamos que reducirán el tiempo de desarrollo y aumentar la calidad.

+0

+1 para esta sugerencia (es lo que usé). Soporte técnico muy receptivo también. – noonand

2

Para aquellos mencionar que no ven la colección Tiendas:

Se añadió la colección de tiendas en Outlook 2007. Por lo tanto, si usted está utilizando una biblioteca de interoperabilidad creado a partir de una versión anterior (en una intentar ser independiente de la versión, esto es muy común), entonces esta sería la razón por la cual no verás la colección de Tiendas.

Sus únicas opciones para obtener los suministros se vayan a realizar una de las siguientes:

  • utilizar una biblioteca de interoperabilidad para Outlook 2007 (esto significa que su código no funcionará para las versiones anteriores de Outlook).
  • Enumere todas las carpetas de nivel superior con el modelo de objetos de Outlook, extraiga el StoreID de cada carpeta y luego use las interfaces CDO o MAPI para obtener más información sobre cada tienda.
  • Enumere la colección InfoStores del objeto de sesión CDO y luego use la colección de campos del objeto Almacén de información para obtener más información sobre cada tienda.
  • O (la forma más difícil) utiliza la llamada extendida MAPI (en C++): IMAPISession :: GetMsgStoresTable.
0

Sí, con Independentsoft PST .NET es posible leer/exportar archivos .pst protegidos con contraseña y encriptados.

0

Encontré algunos recursos directamente de Microsoft que pueden ser útiles para completar esta tarea. A search on MSDN revela lo siguiente.

Tenga en cuenta que cuando se va a añadir una referencia a Microsoft.Office.Interop.Outlook, the documentation insiste en que lo hace a través de la ficha .NET en lugar de la OCM lengüeta.

1

Otra solución opcional: NetPstExtractor

Ésta es una API .NET para leer el archivo PST de Outlook sin instalado Outlook.

Puede encontrar la versión de demostración here.

0

código realmente útil. Si ha pst y almacenar los mensajes en su raíz (sin ningún tipo de directorio), entonces usted puede utilizar el siguiente en el 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); 
     } 
} 
Cuestiones relacionadas