Zarządzanie załącznikami wiadomości

Obsługa załączników w Outlooku

Tworzenie i zapisywanie wiadomości Outlook (plików MSG) wyjaśnia, jak tworzyć i zapisywać wiadomości oraz jak tworzyć pliki MSG z załącznikami. Ten artykuł wyjaśnia, jak zarządzać załącznikami Microsoft Outlook przy użyciu Aspose.Email. Załączniki z pliku wiadomości są dostępne i zapisywane na dysku przy użyciu MapiMessage klasa Załączniki właściwości. Załączniki właściwość jest kolekcją typu MapiAttachmentCollection klasa.

Sprawdź typ załącznika (Inline lub Regular)

Załączniki inline i zwykłe pełnią różne funkcje. Załączniki inline są wizualnie wbudowane w wiadomość e‑mail i zazwyczaj są obrazami lub plikami multimedialnymi. Natomiast zwykłe załączniki są odrębnymi plikami dołączonymi do e‑maila i mogą zawierać różne typy plików. MapiAttachment.IsInline właściwość MapiAttachment klasa pobiera wartość wskazującą, czy załącznik jest wbudowany, czy regularny.

Poniższy przykład kodu wyodrębnia i wyświetla informacje o każdym załączniku w załadowanym MapiMessage, w tym ich wyświetlane nazwy oraz informację, czy są załącznikami inline, czy nie.

var message = MapiMessage.Load(fileName);

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

Sprawdź typ załącznika (IsReference)

Ten MapiAttachment klasa zawiera IsReference właściwość, która pozwala programistom identyfikować załączniki referencyjne w wiadomości. W poniższym przykładzie kodu możesz sprawdzić, czy załącznik jest załącznikiem referencyjnym:

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

Zapisz załączniki z plików MSG

Aby zapisać załączniki z pliku MSG:

  1. Iteruj przez MapiAttachmentCollection kolekcję i pobierz poszczególne załączniki.
  2. Aby zapisać załączniki, wywołaj metodę Save() klasy MapiAttachment.

Poniższy fragment kodu pokazuje, jak zapisać załączniki na lokalnym dysku.

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

Wyodrębnij załączniki z plików MSG sformatowanych jako RTF

Dla wiadomości sformatowanych jako RTF, poniższy kod może być użyty do rozróżnienia i wyodrębnienia załączników, które są inline lub pojawiają się jako ikona w treści wiadomości. Poniższy fragment kodu pokazuje, jak zidentyfikować i wyodrębnić wbudowany załącznik z MSG sformatowanego jako 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);
        }
    }
}

Uzyskaj zagnieżdżone załączniki wiadomości e‑mail

Załączniki OLE osadzone również pojawiają się w MapiMessage klasa kolekcji Attachment. Poniższy przykład kodu analizuje plik wiadomości pod kątem wbudowanych załączników wiadomości i zapisuje go na dysku. MapiMessage statyczna metoda klasy FromProperties() może utworzyć nową wiadomość z wbudowanego załącznika. Poniższy fragment kodu pokazuje, jak uzyskać zagnieżdżone załączniki wiadomości e‑mail.

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

Usuń załączniki

Biblioteka Aspose Outlook zapewnia funkcjonalność usuwania załączników z plików Microsoft Outlook Message (.msg):

  • Wywołaj metodę RemoveAttachments(). Przyjmuje ona ścieżkę do pliku wiadomości jako parametr. Jest zaimplementowana jako metoda publiczna statyczna, więc nie musisz tworzyć obiektu.

Poniższy fragment kodu pokazuje, jak usunąć załączniki.

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

Możesz także wywołać MapiMessage statyczna metoda klasy DestroyAttachments(). Działa szybciej niż RemoveAttachments(), ponieważ metoda RemoveAttachments() parsuje plik wiadomości.

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

Dodaj załączniki MSG

Wiadomość Outlook może zawierać inne wiadomości Microsoft Outlook jako załączniki, zarówno jako zwykłe, jak i osadzone wiadomości. MapiAttachmentCollection udostępnia przeciążone elementy Add metoda tworzenia wiadomości Outlook z obiema typami załączników:

  • Add(string name, byte[] data) – dodaje zwykły załącznik z tablicy bajtów.
  • Add(string name, MapiMessage message) – dodaje inną wiadomość Outlook jako wiadomość osadzoną.

Poniższy fragment kodu pokazuje, jak dodać oba typy załączników do wiadomości.

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

Dodaj załączniki referencyjne do MapiMessages

Ten ReferenceAttachmentOptions klasa upraszcza dodawanie załączników referencyjnych, kapsułkując wszystkie niezbędne właściwości w jednym obiekcie.

Parametry ReferenceAttachmentOptions:

  • sharedLink: Pełny udostępniony link do załącznika dostarczony przez usługę internetową hostującą plik.
  • url: Lokalizacja pliku lub URL zasobu.
  • providerName: Nazwa dostawcy załącznika referencyjnego (np. Google Drive, Dropbox).
  • Przykład: Dodawanie załącznika referencyjnego przy użyciu 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);

Osadzanie wiadomości jako załączniki

Poniższy fragment kodu pokazuje, jak osadzić załącznik pliku MSG w wiadomości.

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

Odczyt osadzonych wiadomości z załączników

Poniższy fragment kodu pokazuje, jak odczytać osadzone wiadomości z załączników.

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

Wstawianie i zamiana załącznika

Aspose.Email API umożliwia wstawianie załączników pod określonym indeksem w wiadomości nadrzędnej. Umożliwia również zastąpienie treści jednego załącznika innym załącznikiem wiadomości.

Wstawianie załączników w określonych miejscach

API Aspose.Email zapewnia możliwość wstawienia załącznika MSG do nadrzędnego MSG przy użyciu metody Insert kolekcji MapiAttachmentCollection MapiAttachmentCollection Insert(int index, string name, MapiMessage msg). Poniższy fragment kodu pokazuje, jak wstawić załącznik w określone miejsce.

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

Zastąp zawartość załącznika

Można tego używać do zastąpienia zawartości osadzonych załączników nowymi przy pomocy metody Replace. Nie można jednak wstawić załącznika z PR_ATTACH_NUM = 4 (na przykład) w kolekcji, której collection.Count = 2. Poniższy fragment kodu pokazuje, jak zastąpić zawartość załącznika.

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

Zmień nazwę załączników w MapiMessage

Możliwe jest edytowanie wartości właściwości DisplayName w załącznikach MapiMessage.

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

Zapisz załączniki z cyfrowo podpisanych wiadomości

Aspose.Email API umożliwia pobranie lub ustawienie wartości wskazującej, czy wiadomość z podpisem Clear‑Signed zostanie zdekodowana. 

Wyodrębnij osadzone obiekty OLE z oledata.mso

Czasami osadzone dane OLE są przedstawiane jako oledata.mso załącznik w MapiAttachment i trzeba je wyodrębnić ręcznie. Te oledata.mso pliki są w formacie Microsoft Compound Document File (MCDF), a obsługa takich plików wykracza poza zakres Aspose.Email. Jednak Aspose.Email może być używany w połączeniu z innymi bibliotekami open‑source, takimi jak OpenMCDF, aby odczytać zawartość tych plików i zapisać ją na dysku. Aspose.Email udostępnia InlineAttachmentExtractor klasa do enumeracji pakietów MSO zawartych w danych binarnych oledata.mso, które można następnie przekazać do biblioteki odczytującej pliki złożone w celu wyodrębnienia zawartości.

Gdy typ ciała wiadomości jest HTML (nie RTF) i w wiadomości znajdują się obiekty OLE, MapiPropertyTag.PR_ATTACH_DATA_OBJ właściwość jest nieobecna. W takim przypadku informacje o obiektach OLE znajdują się w oledata.mso.

Aby wyodrębnić zawartość przy użyciu Aspose.Email i OpenMCDF:

  • Enumeruj pakiety MSO z danych binarnych oledata.mso załącznik.
  • Dla każdego elementu OLE odczytaj plik złożony.
  • Odczytaj strumień o nazwie CONTENTS.
  • Zapisz zawartość do 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++;
        }
    }
}