Läs MS Outlook PST-filer i C# .NET

En Konversationstråd är en sekvens av svar på ett meddelande med en röd tråd. Meddelanden i konversationen kan visas på olika sätt, till exempel i hierarkisk eller kronologisk ordning. För att visa en meddelandetråd identifierar e-postprogram meddelandesvar. De mest populära e-postfilformaten tillhandahåller denna funktion. Konversationstrådar gör det möjligt för läsare att snabbt förstå den övergripande strukturen i en konversation, lyfta fram vissa punkter i konversationer och analysera viktig information. I den här artikeln kommer vi att fokusera på att använda Aspose.Emails PST/MAPI-funktioner för att hitta och gruppera meddelanden efter konversation. För att göra detta kommer vi att implementera en exempelkod som kommer att gå igenom meddelandena i en given mapp, gruppera dem efter konversation och sedan spara varje konversation i en separat diskkatalog.

MAPI-egenskaper som används för att stödja konversationstråden

Eftersom meddelanden i pst lagras som en uppsättning MAPI-egenskaper måste vi definiera MAPI-egenskaper som är associerade med att samla in meddelandesvar. Detta beskrivs i Microsoft Docs-avsnittet. Som det kan ses tillåter egenskapen PidTagConversationIndex att exakt bestämma om ett meddelande är associerat med en viss konversation eller inte. Egenskapen indikerar också den relativa meddelandepositionen i en konversationstråd. Besök sidan för mer information om egenskapen PidTagConversationIndex. Rubriken är de första 22 byten av egenskapsvärdet PidTagConversationIndex. Det är en datadel för att avgöra om meddelandet tillhör en viss konversationstråd.

C# .NET API för att läsa Outlook PST-filer

För att läsa PST-filer använder vi Aspose.Email for .NET. Det är ett fantastiskt bibliotek för att implementera appar för e-postbehandling med .NET. Med hjälp av biblioteket kan du enkelt hantera en mängd olika e-postfilformat. Du kan installera Aspose.Email för .NET via NuGet eller ladda ner dess DLL.

PM> Install-Package Aspose.Email

Gruppera meddelanden i PST efter konversationstråd

För att gruppera meddelanden i PST efter konversationer behöver vi följande:

  • Skapa först en “ConversationThread”-klass. Det är en behållare för att gruppera meddelanden i en konversation.
  • Skapa sedan en metod för att söka och gruppera meddelanden efter konversationen.
  • Slutligen, skapa en metod för att spara konversationstråden i en separat katalog.

Skapa en ConversationThread-klass

Den kommer att ha följande egenskaper.

  • Id: strängrepresentation av konversationsindexhuvudet (22 byte).
  • “Meddelanden”: lista över meddelande-ID:n som finns i konversationstråden.
///<summary>
/// Representerar meddelanden i en konversationstråd.
///</summary>
public class ConversationThread
{
    private string id;
    private List<string> messages;
    
    ///<summary>
    /// Initierar en ny instans av<see cref="ConversationThread"/> klass.
    ///</summary>
    ///<param name="id"> Strängrepresentationen av konversationsindexrubrik.</param>
    public MessageThread(string id)
    {
        this.id = id;
        this.messages = new List<string>();
    }
    
    ///<summary>
    /// Hämtar eller ställer in HEX-strängrepresentationen av konversationsindexhuvudet (22 byte).
    ///</summary>
    public string Id { get => id; set => id = value; }
    
    ///<summary>
    /// Får en lista över meddelande-ID:n som finns i en konversationstråd.
    ///</summary>
    public List<string> Messages { get => messages; }
}

Skapa en metod för att söka och gruppera meddelanden efter konversation

Efter att ha skapat klassen ‘ConversationThread’ kan vi fokusera på att skriva en metod som gör följande:

  • Gå igenom alla meddelanden i mappen. Av prestandaskäl kommer vi endast att läsa meddelandeidentifieraren med metoden EnumerateMessagesEntryId.
  • För varje meddelande extraherar vi egenskapen PidTagConversationIndex med metoden ExtractProperty.
  • Meddelanden som har samma första 22 byte av “PidTagConversationIndex” egenskapsvärde tillhör samma konversation. Vi kommer att lägga till meddelande-ID till listan som representeras av ‘Messages’-egenskapen för motsvarande ‘ConversationThread’-klassinstans.
  • Returnera listan över “ConversationThread”-instanser.
using Aspose.Email.Mapi;
using Aspose.Email.Storage.Pst;

public List<ConversationThread> GroupMessagesByThread(PersonalStorage pst, FolderInfo folder)
{
    // Resultat
    var list = new List<ConversationThread>();
        
    foreach (var entryId in folder.EnumerateMessagesEntryId())
    {
        // Extrahera egenskapen PidTagConversationIndex och dess rubrikvärde (22 byte).
        var convIndexTag = KnownPropertyList.ConversationIndex.Tag;
        var convIndexProperty = pst.ExtractProperty(Convert.FromBase64String(entryId), convIndexTag);
        var convIndexHeader = (convIndexProperty != null && convIndexProperty.Data != null) ? convIndexProperty.Data.Take(22).ToArray() : null;
        var convIndexHeaderString = convIndexHeader != null ? 
			      BitConverter.ToString(convIndexHeader).Replace('-', '') : null;
        
        if (convIndexHeaderString != null)
        {
            var convThread = list.Find(x => x.Id == convIndexHeaderString);
            
            if (convThread == null)
            {
                convThread = new ConversationThread(convIndexHeaderString);
                convThread.Messages.Add(entryId);
                list.Add(convThread);
            }
            else
            {
                convThread.Messages.Add(entryId);
            }
        }
    }
        
    return list.Where(x => x.Messages.Count > 1).ToList();
}

Skapa en metod för att spara konversationstråden i en separat katalog

Slutligen, låt oss spara konversationerna i katalogerna.

För varje “ConversationThread”-instans gör du följande:

  • Skapa en separat katalog med namnet på trådämnet.
  • Räkna upp identifierarna i egenskapen ConversationThread.Messages, för varje identifierare extrahera ett meddelande med metoden ExtractMessage och spara meddelandet i den skapade katalogen med metoden Save.
public void SaveThreads(List<ConversationThread> list, string outDirectory)
{
    var invalidChars = Path.GetInvalidFileNameChars();
    
    foreach (var item in list)
    {
        string? threadDirectory = null;
        var i = item.Messages.Count - 1;
        
        foreach (var entryId in item.Messages)
        {
            var msg = pst.ExtractMessage(entryId);
            
            if (threadDirectory == null)
            {
                var threadName = new string(msg.ConversationTopic.Where(x => !invalidChars.Contains(x)).ToArray()).Trim();
                threadDirectory = Path.Combine(outDirectory, threadName);
                Directory.CreateDirectory(threadDirectory);
            }
            
            msg.Save(Path.Combine(threadDirectory, $"{i--}.msg"));
        }
        
        threadDirectory = null;
    }
}

Skaffa en gratis API-licens

Du kan använda Aspose.Email för .NET utan utvärderingsbegränsningar med en gratis temporär licens.

Slutsats

Den här artikeln visar hur du använder Aspose.Email för att söka efter konversationsrelaterade meddelanden i PST. Genom att ytterligare utforska PidTagConversationIndex dokumentationen kan du också komplicera implementeringen genom att lägga till, till exempel, hierarkisk sortering av konversationsmeddelanden. Du kan lära dig mer om Aspose.Email med hjälp av dokumentationen. Om du har några frågor kan du göra ett inlägg på vårt forum.

Se även