Gerenciando Anexos de Mensagens

Manipulando Anexos no Outlook

Criando e Salvando Arquivos de Mensagem Outlook (MSG) explica como criar e salvar mensagens, e como criar arquivos MSG com anexos. Este artigo explica como gerenciar anexos do Microsoft Outlook com Aspose.Email. Anexos de um arquivo de mensagem são acessados e salvos no disco usando o MapiMessage classe Anexos propriedade. O Anexos propriedade é uma coleção do tipo MapiAttachmentCollection classe.

Verificar Tipo de Anexo (Inline ou Regular)

Anexos inline e regulares servem a propósitos diferentes. Anexos inline são integrados visualmente na mensagem de e‑mail e geralmente são imagens ou arquivos de mídia. Enquanto isso, anexos regulares são arquivos separados anexados ao e‑mail e podem incluir vários tipos de arquivos. O MapiAttachment.IsInline propriedade do MapiAttachment classe obtém um valor que indica se o anexo é embutido ou regular.

O exemplo de código a seguir extrai e exibe informações sobre cada anexo na MapiMessage carregada, incluindo seus nomes de exibição e se são anexos inline ou não.

var message = MapiMessage.Load(fileName);

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

Verificar Tipo de Anexo (IsReference)

O MapiAttachment classe inclui o IsReference propriedade que permite aos desenvolvedores identificar anexos de referência em uma mensagem. Com o exemplo de código a seguir, você pode verificar se um anexo é um anexo de referência:

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

Salvar Anexos de Arquivos MSG

Para salvar anexos de um arquivo MSG:

  1. Itere através do MapiAttachmentCollection coleção e obtenha os anexos individuais.
  2. Para salvar os anexos, chame o método Save() da classe MapiAttachment.

O trecho de código a seguir mostra como salvar anexos no disco local.

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

Extrair Anexos de Arquivos MSG Formatados em RTF

Para mensagens formatadas como RTF, o código a seguir pode ser usado para diferenciar e extrair anexos que são Inline ou aparecem como Ícone no corpo da mensagem. O trecho de código a seguir mostra como Identificar e Extrair um anexo incorporado de um MSG formatado como 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);
        }
    }
}

Obter Anexos de Mensagens de Correio Aninhadas

Anexos OLE incorporados também aparecem no MapiMessage coleção de anexos da classe. O exemplo de código a seguir analisa um arquivo de mensagem em busca de anexos de mensagem incorporados e o salva no disco. O MapiMessage O método estático FromProperties() da classe pode criar uma nova mensagem a partir de um anexo incorporado. O trecho de código a seguir mostra como obter anexos de mensagens de correio aninhadas.

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

Remover Anexos

A biblioteca Aspose Outlook fornece a funcionalidade de remover anexos de arquivos Microsoft Outlook Message (.msg):

  • Chame o método RemoveAttachments(). Ele recebe o caminho do arquivo de mensagem como parâmetro. É implementado como um método estático público, portanto você não precisa instanciar o objeto.

O trecho de código a seguir mostra como remover anexos.

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

Você também pode chamar o MapiMessage método estático da classe DestroyAttachments(). Funciona mais rápido que RemoveAttachments(), porque o método RemoveAttachments() analisa o arquivo da mensagem.

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

Adicionar Anexos MSG

Uma mensagem do Outlook pode conter outras mensagens do Microsoft Outlook em anexos, seja como mensagens regulares ou incorporadas. O MapiAttachmentCollection fornece membros sobrecarregados do Adicionar método para criar mensagens do Outlook com ambos os tipos de anexos:

  • Add(string name, byte[] data) – adiciona um anexo regular a partir de um array de bytes.
  • Add(string name, MapiMessage message) – adiciona outra mensagem do Outlook como mensagem incorporada.

O trecho de código a seguir mostra como adicionar ambos os tipos de anexos a uma mensagem.

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

Adicionar Anexos de Referência a MapiMessages

O ReferenceAttachmentOptions a classe simplifica a adição de anexos de referência encapsulando todas as propriedades necessárias em um único objeto.

Parâmetros de ReferenceAttachmentOptions:

  • sharedLink: Um link compartilhado totalmente qualificado para o anexo fornecido pelo serviço web que hospeda o arquivo.
  • url: A localização do arquivo ou URL do recurso.
  • providerName: O nome do provedor de anexo de referência (por exemplo, Google Drive, Dropbox).
  • Exemplo: Adicionando um Anexo de Referência com 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);

Incorporar Mensagens como Anexos

O trecho de código a seguir mostra como incorporar um anexo de arquivo MSG a uma mensagem.

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

Ler Mensagens Incorporadas a partir de Anexos

O trecho de código a seguir mostra como ler mensagens incorporadas a partir de anexos.

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

Inserindo e Substituindo Anexo

Aspose.Email API oferece a capacidade de inserir anexos em um índice específico na mensagem principal. Também oferece a funcionalidade de substituir o conteúdo de um anexo por outro anexo de mensagem.

Inserir Anexos em Locais Específicos

A API Aspose.Email fornece a capacidade de inserir um anexo MSG em um MSG pai usando o método Insert da MapiAttachmentCollection MapiAttachmentCollection Insert(int index, string name, MapiMessage msg). O trecho de código a seguir mostra como inserir um anexo em um local específico.

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

Substituir Conteúdo do Anexo

Isso pode ser usado para substituir o conteúdo de anexos incorporados pelos novos usando o método Replace. No entanto, não pode ser usado para inserir um anexo com PR_ATTACH_NUM = 4 (por exemplo) na coleção com collection.Count = 2. O trecho de código a seguir mostra como substituir o conteúdo de um anexo.

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

Renomear Anexos em MapiMessage

É possível editar o valor da propriedade DisplayName nos anexos de MapiMessage.

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

Salvar Anexos de Mensagens Assinadas Digitalmente

Aspose.Email API oferece a capacidade de obter ou definir um valor que indica se a mensagem assinada em claro será decodificada. 

Extrair Objetos OLE Incorporados de oledata.mso

Às vezes, os dados OLE incorporados são representados como um oledata.mso anexo em um MapiAttachment e precisam ser extraídos manualmente. Estes oledata.mso os arquivos estão no formato Microsoft Compound Document File (MCDF), e o suporte a tais arquivos está fora do escopo do Aspose.Email. Contudo, Aspose.Email pode ser usado em combinação com outras bibliotecas de código aberto, como OpenMCDF, para ler o conteúdo desses arquivos e salvá‑los no disco. Aspose.Email fornece o InlineAttachmentExtractor classe para enumerar os pacotes MSO contidos nos dados binários de oledata.mso, que então pode ser passado para uma biblioteca de leitura de arquivos compostos para extração de conteúdo.

Quando o tipo do corpo da mensagem é HTML (não RTF) e há objetos OLE na mensagem, o MapiPropertyTag.PR_ATTACH_DATA_OBJ a propriedade está ausente. Nesse caso, as informações sobre os objetos OLE estão contidas em oledata.mso.

Para extrair o conteúdo usando Aspose.Email e OpenMCDF:

  • Enumere os pacotes MSO a partir dos dados binários do oledata.mso anexo.
  • Para cada item OLE, leia o arquivo composto.
  • Leia o stream chamado CONTENTS.
  • Salve o conteúdo em um 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++;
        }
    }
}