การจัดการไฟล์แนบของข้อความ

การจัดการไฟล์แนบใน Outlook

การสร้างและบันทึกไฟล์ข้อความ Outlook (MSG) อธิบายวิธีสร้างและบันทึกข้อความ รวมถึงวิธีสร้างไฟล์ MSG พร้อมไฟล์แนบ บทความนี้อธิบายวิธีจัดการไฟล์แนบของ Microsoft Outlook ด้วย Aspose.Email ไฟล์แนบจากไฟล์ข้อความจะถูกเข้าถึงและบันทึกลงดิสก์โดยใช้ MapiMessage คลาส ไฟล์แนบ คุณสมบัติ. The ไฟล์แนบ คุณสมบัตินี้เป็นคอลเลกชันของประเภท MapiAttachmentCollection คลาส.

ตรวจสอบประเภทไฟล์แนบ (อินไลน์หรือทั่วไป)

ไฟล์แนบแบบอินไลน์และไฟล์แนบทั่วไปมีจุดประสงค์ที่แตกต่างกัน ไฟล์แนบแบบอินไลน์จะแทรกเข้าไปในข้อความอีเมลอย่างเป็นภาพและโดยทั่วไปเป็นรูปภาพหรือไฟล์สื่อ ส่วนไฟล์แนบทั่วไปเป็นไฟล์แยกที่แนบกับอีเมลและอาจรวมไฟล์หลายประเภท MapiAttachment.IsInline คุณสมบัติของ MapiAttachment คลาสรับค่าที่บ่งชี้ว่าไฟล์แนบเป็น inline หรือปกติ.

ตัวอย่างโค้ดต่อไปนี้จะสกัดและแสดงข้อมูลเกี่ยวกับไฟล์แนบแต่ละไฟล์ใน MapiMessage ที่โหลดรวมถึงชื่อที่แสดงและว่ามีเป็นไฟล์แนบแบบอินไลน์หรือไม่

var message = MapiMessage.Load(fileName);

foreach (var attach in message.Attachments)
{
    Console.WriteLine($"{attach.DisplayName} : {attach.IsInline}");
}

ตรวจสอบประเภทไฟล์แนบ (IsReference)

นี้ MapiAttachment คลาสนี้รวมถึง IsReference คุณสมบัติที่ช่วยให้นักพัฒนาสามารถระบุไฟล์แนบอ้างอิงในข้อความได้ ด้วยตัวอย่างโค้ดต่อไปนี้ คุณสามารถตรวจสอบได้ว่าไฟล์แนบเป็นไฟล์แนบอ้างอิงหรือไม่:

foreach (var attachment in msg.Attachments)
{
    if (attachment.IsReference)
    {
        // Process reference attachment
    }
}

บันทึกไฟล์แนบจากไฟล์ MSG

เพื่อบันทึกไฟล์แนบจากไฟล์ MSG:

  1. วนซ้ำผ่าน MapiAttachmentCollection คอลเลกชันและดึงไฟล์แนบแต่ละรายการ
  2. เพื่อบันทึกไฟล์แนบ ให้เรียกเมธอด Save() ของคลาส MapiAttachment.

โค้ดตัวอย่างต่อไปนี้แสดงวิธีบันทึกไฟล์แนบลงในดิสก์ท้องถิ่น

// Create an instance of MapiMessage from file
MapiMessage message = MapiMessage.FromFile(dataDir + fileName);

// Iterate through the attachments collection
foreach (MapiAttachment attachment in message.Attachments)
{
    // Save the individual attachment
    attachment.Save(dataDir + attachment.FileName);
}

สกัดไฟล์แนบจากไฟล์ MSG ที่จัดรูปแบบเป็น RTF

สำหรับข้อความที่จัดรูปแบบเป็น RTF โค้ดต่อไปนี้สามารถใช้เพื่อแยกแยะและสกัดไฟล์แนบที่เป็นอินไลน์หรือแสดงเป็นไอคอนในส่วนของข้อความ ตัวอย่างโค้ดต่อไปนี้แสดงวิธีระบุและสกัดไฟล์แนบที่ฝังอยู่จาก MSG ที่จัดรูปแบบเป็น RTF


var eml = MapiMessage.Load("MSG file with RTF Formatting.msg");

foreach (var attachment in eml.Attachments)
{
    if (IsAttachmentInline(attachment))
    {
        try
        {
            SaveAttachment(attachment, Guid.NewGuid().ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

static bool IsAttachmentInline(MapiAttachment attachment)
{
    foreach (var property in attachment.ObjectData.Properties.Values)
    {
        if (property.Name == "\x0003ObjInfo")
        {
            var odtPersist1 = BitConverter.ToUInt16(property.Data, 0);
            return (odtPersist1 & (1 << (7 - 1))) == 0;
        }
    }
    return false;
}

static void SaveAttachment(MapiAttachment attachment, string fileName)
{
    foreach (var property in attachment.ObjectData.Properties.Values)
    {
        if (property.Name == "Package")
        {
            using var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
            fs.Write(property.Data, 0, property.Data.Length);
        }
    }
}

ดึงไฟล์แนบของข้อความเมลที่ซ้อนกัน

ไฟล์แนบ OLE ที่ฝังอยู่ยังปรากฏใน MapiMessage คลาสคอลเลกชัน Attachment ตัวอย่างโค้ดต่อไปนี้ทำการแยกไฟล์ข้อความเพื่อหไฟล์แนบของข้อความที่ฝังอยู่และบันทึกลงดิสก์ MapiMessage เมธอดสแตติก FromProperties() ของคลาส สามารถสร้างข้อความใหม่จากไฟล์แนบที่ฝังไว้ ตัวอย่างโค้ดต่อไปนี้แสดงวิธีดึงไฟล์แนบของข้อความเมลที่ซ้อนกัน

// Create a MapiMessage object from the individual attachment
MapiMessage getAttachment = MapiMessage.FromProperties(attachment.ObjectData.Properties);

// Convert the embedded message to a MailMessage and save it to disk
MailMessage mailMessage = getAttachment.ToMailMessage(new MailConversionOptions());
mailMessage.Save(dataDir + @"NestedMailMessageAttachments_out.eml", SaveOptions.DefaultEml);

ลบไฟล์แนบ

ไลบรารี Aspose Outlook ให้ฟังก์ชันการลบไฟล์แนบจากไฟล์ Microsoft Outlook Message (.msg):

  • เรียกเมธอด RemoveAttachments() ซึ่งรับพาธของไฟล์ข้อความเป็นพารามิเตอร์ ถูกกำหนดเป็นเมธอดสาธารณะแบบสถิติ จึงไม่จำเป็นต้องสร้างอ็อบเจกต์.

โค้ดต่อไปนี้แสดงวิธีลบไฟล์แนบ.

MapiMessage.RemoveAttachments(dataDir + "AttachmentsToRemove_out.msg");

คุณยังสามารถเรียกใช้ MapiMessage เมธอดสแตติกของคลาส DestroyAttachments(). ทำงานเร็วกว่า RemoveAttachments() เพราะเมธอด RemoveAttachments() จะพาร์สไฟล์ข้อความ.

MapiMessage.DestroyAttachments(dataDir + "AttachmentsToDestroy_out.msg");

เพิ่มไฟล์แนบ MSG

ข้อความ Outlook สามารถมีข้อความ Microsoft Outlook อื่นเป็นไฟล์แนบได้ ไม่ว่าจะเป็นข้อความทั่วไปหรือข้อความที่ฝังไว้ MapiAttachmentCollection ให้สมาชิกที่มีการ overload ของ Add เมธอดเพื่อสร้างข้อความ Outlook ที่มีไฟล์แนบทั้งสองประเภท:

  • Add(string name, byte[] data) – เพิ่มไฟล์แนบทั่วไปจากอาเรย์ไบต์.
  • Add(string name, MapiMessage message) – เพิ่มข้อความ Outlook อื่นเป็นข้อความฝัง.

โค้ดต่อไปนี้แสดงวิธีเพิ่มไฟล์แนบชนิดทั้งสองลงในข้อความ.

MapiMessage message = new MapiMessage("from@test.com", "to@test.com", "Subj", "This is a message body");

// Add a regular attachment from a byte array
message.Attachments.Add("note.txt", File.ReadAllBytes(dataDir + "note.txt"));

// Add another Outlook message as an embedded message
MapiMessage attachMsg = MapiMessage.FromFile(dataDir + "Message.msg");
message.Attachments.Add("Weekly report.msg", attachMsg);

message.Save(dataDir + "WithAttachments_out.msg");

เพิ่มไฟล์แนบอ้างอิงให้กับ MapiMessages

นี้ ReferenceAttachmentOptions คลาสนี้ทำให้การเพิ่มไฟล์แนบอ้างอิงง่ายขึ้นโดยการรวมคุณสมบัติที่จำเป็นทั้งหมดไว้ในออบเจ็กต์เดียว

พารามิเตอร์ของ ReferenceAttachmentOptions:

  • sharedLink: ลิงก์แชร์เต็มรูปแบบไปยังไฟล์แนบที่ให้โดยบริการเว็บที่โฮสต์ไฟล์
  • url: ตำแหน่งไฟล์หรือ URL ของทรัพยากร.
  • providerName: ชื่อของผู้ให้บริการไฟล์แนบอ้างอิง (เช่น Google Drive, Dropbox).
  • ตัวอย่าง: การเพิ่มไฟล์แนบอ้างอิงด้วย ReferenceAttachmentOptions
var options = new ReferenceAttachmentOptions(
    "https://drive.google.com/file/d/1HJ-M3F2qq1oRrTZ2GZhUdErJNy2CT3DF/",
    "https://drive.google.com/drive/my-drive",
    "GoogleDrive");

// Add reference attachment
msg.Attachments.Add("Document.pdf", options);

ฝังข้อความเป็นไฟล์แนบ

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีฝังไฟล์แนบ MSG ลงในข้อความ

MapiMessage message = new MapiMessage("from@test.com", "to@test.com", "Subj", "This is a message body");
MapiMessage attachMsg = MapiMessage.FromFile(dataDir + "Message.msg");
message.Attachments.Add("Weekly report.msg", attachMsg);
message.Save(dataDir + "WithEmbeddedMsg_out.msg");

อ่านข้อความที่ฝังอยู่จากไฟล์แนบ

โค้ดตัวอย่างต่อไปนี้แสดงวิธีการอ่านข้อความที่ฝังอยู่จากไฟล์แนบ

var message = MapiMessage.FromFile(fileName);
if (message.Attachments[0].ObjectData.IsOutlookMessage)
{
    var getData = message.Attachments[0].ObjectData.ToMapiMessage();
}

การแทรกและแทนที่ไฟล์แนบ

Aspose.Email API ให้ความสามารถในการแทรกไฟล์แนบที่ตำแหน่งเฉพาะในข้อความพาเรนท์ นอกจากนี้ยังให้ความสะดวกในการแทนที่เนื้อหาของไฟล์แนบด้วยไฟล์แนบจากข้อความอื่น.

แทรกไฟล์แนบในตำแหน่งเฉพาะ

Aspose.Email API มีความสามารถในการแทรกไฟล์แนบ MSG ลงใน MSG พาเรนต์โดยใช้เมธอด Insert ของ MapiAttachmentCollection ซึ่งมีรูปแบบ MapiAttachmentCollection Insert(int index, string name, MapiMessage msg) ตัวอย่างโค้ดต่อไปนี้แสดงวิธีแทรกไฟล์แนบในตำแหน่งที่กำหนด

var message = MapiMessage.FromFile(fileName);
var memoryStream = new MemoryStream();
message.Attachments[2].Save(memoryStream);
           
var getData = MapiMessage.FromStream(memoryStream);
message.Attachments.Insert(1, "new 11", getData);

แทนที่เนื้อหาไฟล์แนบ

นี่สามารถใช้แทนที่เนื้อหาไฟล์แนบที่ฝังอยู่ด้วยไฟล์ใหม่โดยใช้เมธอด Replace อย่างไรก็ตาม ไม่สามารถใช้แทรกไฟล์แนบที่มี PR_ATTACH_NUM = 4 (เช่น) ในคอลเลกชันที่มี collection.Count = 2 ได้ โค้ดตัวอย่างต่อไปนี้แสดงวิธีการแทนที่เนื้อหาไฟล์แนบ.

var message = MapiMessage.FromFile(fileName);
var memoryStream = new MemoryStream();
message.Attachments[2].Save(memoryStream);
var getData = MapiMessage.FromStream(memoryStream);
message.Attachments.Replace(1, "new 1", getData);

เปลี่ยนชื่อไฟล์แนบใน MapiMessage

สามารถแก้ไขค่าคุณสมบัติ DisplayName ในไฟล์แนบของ MapiMessage ได้

var msg = MapiMessage.Load(fileName);
msg.Attachments[0].DisplayName = "New display name 1";
msg.Attachments[1].DisplayName = "New display name 2";

บันทึกไฟล์แนบจากข้อความที่ลงลายเซ็นดิจิทัล

Aspose.Email API ให้ความสามารถในการรับหรือกำหนดค่าที่บ่งชี้ว่าข้อความที่เซ็นชัดจะถูกถอดรหัสหรือไม่. 

ดึงอ็อบเจ็กต์ OLE ฝังจาก oledata.mso

บางครั้งข้อมูล OLE ฝังจะแสดงเป็น oledata.mso ไฟล์แนบใน MapiAttachment และต้องดึงออกด้วยตนเอง สิ่งเหล่านี้ oledata.mso ไฟล์เหล่านี้อยู่ในรูปแบบ Microsoft Compound Document File (MCDF) และการสนับสนุนไฟล์ดังกล่าวอยู่นอกขอบเขตของ Aspose.Email อย่างไรก็ตาม Aspose.Email สามารถใช้ร่วมกับไลบรารีโอเพ่นซอร์สอื่น ๆ เช่น OpenMCDF, เพื่ออ่านเนื้อหาของไฟล์เหล่านี้และบันทึกลงดิสก์ Aspose.Email ให้ InlineAttachmentExtractor คลาสเพื่อแยกรายการแพ็กเกจ MSO ที่อยู่ในข้อมูลไบนารีของ oledata.msoซึ่งสามารถส่งต่อไปยังไลบรารีการอ่านไฟล์คอมพาวด์เพื่อดึงเนื้อหา

เมื่อประเภทเนื้อความของข้อความเป็น HTML (ไม่ใช่ RTF) และมีอ็อบเจ็กต์ OLE อยู่ในข้อความ, MapiPropertyTag.PR_ATTACH_DATA_OBJ คุณสมบัติเขาสาถูกขาด ในกรณีนี้ข้อมูลเกี่ยวกับอ็อบเจ็กต์ OLE ถูกเก็บไว้ใน oledata.mso.

เพื่อดึงเนื้อหาโดยใช้ Aspose.Email และ OpenMCDF:

  • แยกรายการแพ็กเกจ MSO จากข้อมูลไบนารีของ oledata.mso ไฟล์แนบ
  • สำหรับแต่ละรายการ OLE, อ่านไฟล์คอมพาวด์
  • อ่านสตรีมที่ชื่อ CONTENTS.
  • บันทึกเนื้อหาไปยัง FileStream.
// The path to the File directory
string dataDir = RunExamples.GetDataDir_Email();

MapiMessage msg = MapiMessage.FromFile(dataDir + "double.msg");
foreach (MapiAttachment mapiAttachment in msg.Attachments)
{
    if (mapiAttachment.LongFileName == "oledata.mso")
    {
        IDictionary<string, byte[]> oledata = InlineAttachmentExtractor.EnumerateMsoPackage(new MemoryStream(mapiAttachment.BinaryData));
        int index = 0;
        foreach (var oleItem in oledata)
        {
            // Using the OpenMCDF library
            CompoundFile cf = new CompoundFile(new MemoryStream(oleItem.Value));
            CFStream contents = cf.RootStorage.GetStream("CONTENTS");
            using (FileStream fs = File.OpenWrite(index + ".pdf"))
            {
                byte[] data = contents.GetData();
                fs.Write(data, 0, data.Length);
                fs.Flush();
                fs.Close();
            }
            index++;
        }
    }
}