قراءة ملفات MS Outlook PST في C# .NET

إن سلسلة المحادثات عبارة عن سلسلة من الردود على رسالة ذات موضوع مشترك. يمكن عرض الرسائل داخل المحادثة بطرق مختلفة ، مثل الترتيب الهرمي أو الزمني. لعرض موضوع الرسالة ، حدد تطبيقات البريد الإلكتروني الردود على الرسائل. توفر تنسيقات ملفات البريد الإلكتروني الأكثر شيوعًا هذه الميزة. تتيح سلاسل المحادثات للقراء فهم الهيكل العام للمحادثة بسرعة ، وتسليط الضوء على نقاط معينة من المحادثات ، وتحليل المعلومات المهمة. سنركز في هذه المقالة على استخدام ميزات PST / MAPI الخاصة بـ Aspose.Email للعثور على الرسائل وتجميعها حسب المحادثة. للقيام بذلك ، سنقوم بتنفيذ نموذج التعليمات البرمجية التي ستجتاز الرسائل في مجلد معين ، وتجميعها حسب المحادثة ، ثم حفظ كل محادثة في دليل قرص منفصل.

خصائص MAPI التي يتم استخدامها لدعم “مؤشر ترابط المحادثة”

نظرًا لأنه يتم تخزين الرسائل في pst كمجموعة من خصائص MAPI ، نحتاج إلى تحديد خصائص MAPI المرتبطة بتجميع ردود الرسائل. هذا موضح في قسم مُحرر مستندات Microsoft. كما يمكن رؤيته ، تسمح خاصية PidTagConversationIndex بتحديد ما إذا كانت الرسالة مرتبطة بمحادثة معينة أم لا. تشير الخاصية أيضًا إلى موضع الرسالة النسبي ضمن سلسلة محادثات. قم بزيارة الصفحة لمزيد من المعلومات حول خاصية PidTagConversationIndex. الرأس هو أول 22 بايت من قيمة الخاصية “PidTagConversationIndex”. إنه جزء من البيانات لتحديد ما إذا كانت الرسالة تنتمي إلى سلسلة محادثات معينة.

C# .NET API لقراءة ملفات Outlook PST

من أجل قراءة ملفات PST ، سنستخدم Aspose.Email for .NET. إنها مكتبة رائعة لتنفيذ تطبيقات معالجة البريد الإلكتروني باستخدام .NET. باستخدام المكتبة ، يمكنك بسهولة التعامل مع الكثير من تنسيقات ملفات البريد الإلكتروني المختلفة. يمكنك تثبيت Aspose.Email لـ .NET عبر NuGet أو تنزيل DLL الخاص به.

PM> Install-Package Aspose.Email

تجميع الرسائل في PST حسب سلسلة المحادثة

لتجميع الرسائل في PST حسب المحادثات ، نحتاج إلى ما يلي:

  • أولاً ، قم بإنشاء فئة “ConversationThread”. إنها حاوية لتجميع الرسائل داخل محادثة.
  • بعد ذلك ، قم بإنشاء طريقة للبحث عن الرسائل وتجميعها حسب المحادثة.
  • أخيرًا ، قم بإنشاء طريقة لحفظ سلسلة المحادثات في دليل منفصل.

قم بإنشاء فئة ConversationThread

سيكون لها الخصائص التالية.

  • “المعرّف”: تمثيل سلسلة لرأس فهرس المحادثة (22 بايت).
  • “الرسائل”: قائمة بمعرفات الرسائل الموجودة في سلسلة المحادثة.
///<summary>
/// يمثل الرسائل ضمن سلسلة محادثات.
///</summary>
public class ConversationThread
{
    private string id;
    private List<string> messages;
    
    ///<summary>
    /// تهيئة نسخة جديدة من<see cref="ConversationThread"/> صف دراسي.
    ///</summary>
    ///<param name="id"> تمثيل السلسلة لرأس فهرس المحادثة.</param>
    public MessageThread(string id)
    {
        this.id = id;
        this.messages = new List<string>();
    }
    
    ///<summary>
    /// الحصول على أو تعيين تمثيل سلسلة HEX لرأس فهرس المحادثة (22 بايت).
    ///</summary>
    public string Id { get => id; set => id = value; }
    
    ///<summary>
    /// الحصول على قائمة بمعرفات الرسائل الموجودة ضمن سلسلة محادثات.
    ///</summary>
    public List<string> Messages { get => messages; }
}

قم بإنشاء طريقة للبحث عن الرسائل وتجميعها حسب المحادثة

بعد إنشاء فئة “ConversationThread” ، يمكننا التركيز على كتابة طريقة تقوم بما يلي:

  • تصفح جميع الرسائل الموجودة في المجلد. لأسباب تتعلق بالأداء ، سنقرأ فقط معرّف الرسالة باستخدام طريقة EnumerateMessagesEntryId.
  • لكل رسالة سنقوم باستخراج خاصية PidTagConversationIndex باستخدام طريقة ExtractProperty.
  • الرسائل التي لها نفس البايتات الـ 22 الأولى من قيمة خاصية PidTagConversationIndex تنتمي إلى نفس المحادثة. سنضيف معرف الرسالة إلى القائمة الممثلة بخاصية “Messages” لمثيل فئة “ConversationThread” المقابل.
  • قم بإعادة قائمة مثيلات “ConversationThread”.
using Aspose.Email.Mapi;
using Aspose.Email.Storage.Pst;

public List<ConversationThread> GroupMessagesByThread(PersonalStorage pst, FolderInfo folder)
{
    // نتيجة
    var list = new List<ConversationThread>();
        
    foreach (var entryId in folder.EnumerateMessagesEntryId())
    {
        // استخراج خاصية PidTagConversationIndex وقيمتها الرأسية (22 بايت).
        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();
}

قم بإنشاء طريقة لحفظ سلسلة المحادثات في دليل منفصل

أخيرًا ، دعنا نحفظ المحادثات في الدلائل.

لكل حالة من حالات “ConversationThread” ، قم بما يلي:

  • قم بإنشاء دليل منفصل باسم موضوع الموضوع.
  • قم بتعداد المعرفات في خاصية “ConversationThread.Messages” ، لكل معرف استخراج رسالة باستخدام طريقة ExtractMessage وحفظ الرسالة في الدليل الذي تم إنشاؤه باستخدام طريقة حفظ.
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;
    }
}

احصل على ترخيص API مجاني

يمكنك استخدام Aspose.Email لـ .NET بدون قيود تقييمية باستخدام ترخيص مؤقت مجاني.

استنتاج

توضح هذه المقالة كيفية استخدام Aspose.Email للبحث عن الرسائل المتعلقة بالمحادثة في PST. من خلال استكشاف وثائق PidTagConversationIndex ، يمكنك أيضًا تعقيد التنفيذ عن طريق إضافة ، على سبيل المثال ، الفرز الهرمي لرسائل المحادثة. يمكنك معرفة المزيد عن Aspose.Email باستخدام التوثيق. في حال كان لديك أي أسئلة ، يمكنك إرسالها إلى المنتدى.

أنظر أيضا