You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
20 KiB
422 lines
20 KiB
using System;
|
|
using System.IO;
|
|
using DocumentServices.Modules.Readers.MsgReader.Outlook;
|
|
using Microsoft.WindowsAPICodePack.Shell;
|
|
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
|
|
|
|
namespace MsgMapper
|
|
{
|
|
internal class Mapper
|
|
{
|
|
#region MapEmailPropertiesToExtendedFileAttributes
|
|
/// <summary>
|
|
/// Maps all the filled <see cref="Storage.Message"/> properties to the corresponding extended file attributes
|
|
/// </summary>
|
|
/// <param name="message">The <see cref="Storage.Message"/> object</param>
|
|
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
|
|
private void MapEmailPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
|
|
{
|
|
// From
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
|
|
|
|
// Sent on
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
|
|
|
|
// To
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.ToAddress,
|
|
GetEmailRecipients(message, Storage.Recipient.RecipientType.To, false, false));
|
|
|
|
// CC
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.CcAddress,
|
|
GetEmailRecipients(message, Storage.Recipient.RecipientType.Cc, false, false));
|
|
|
|
// BCC
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.BccAddress,
|
|
GetEmailRecipients(message, Storage.Recipient.RecipientType.Bcc, false, false));
|
|
|
|
// Subject
|
|
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
|
|
|
|
// Urgent
|
|
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
|
|
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
|
|
|
|
// Attachments
|
|
var attachments = GetAttachmentNames(message);
|
|
if (string.IsNullOrEmpty(attachments))
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
|
|
}
|
|
else
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
|
|
}
|
|
|
|
// Clear properties
|
|
propertyWriter.WriteProperty(SystemProperties.System.StartDate, null);
|
|
propertyWriter.WriteProperty(SystemProperties.System.DueDate, null);
|
|
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, null);
|
|
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, null);
|
|
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, null);
|
|
|
|
// Follow up
|
|
if (message.Flag != null)
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.IsFlagged, true);
|
|
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, message.Flag.Request);
|
|
|
|
// Flag status text
|
|
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, message.Task.StatusText);
|
|
|
|
// When complete
|
|
if (message.Task.Complete != null && (bool)message.Task.Complete)
|
|
{
|
|
// Flagged complete
|
|
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, true);
|
|
|
|
// Task completed date
|
|
if (message.Task.CompleteTime != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, (DateTime)message.Task.CompleteTime);
|
|
}
|
|
else
|
|
{
|
|
// Flagged not complete
|
|
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, false);
|
|
|
|
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, null);
|
|
|
|
// Task startdate
|
|
if (message.Task.StartDate != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.StartDate, (DateTime)message.Task.StartDate);
|
|
|
|
// Task duedate
|
|
if (message.Task.DueDate != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.DueDate, (DateTime)message.Task.DueDate);
|
|
}
|
|
}
|
|
|
|
// Categories
|
|
var categories = message.Categories;
|
|
if (categories != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
|
|
}
|
|
#endregion
|
|
|
|
#region MapAppointmentPropertiesToExtendedFileAttributes
|
|
/// <summary>
|
|
/// Maps all the filled <see cref="Storage.Appointment"/> properties to the corresponding extended file attributes
|
|
/// </summary>
|
|
/// <param name="message">The <see cref="Storage.Message"/> object</param>
|
|
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
|
|
private void MapAppointmentPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
|
|
{
|
|
// From
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
|
|
|
|
// Sent on
|
|
if (message.SentOn != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
|
|
|
|
// Subject
|
|
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
|
|
|
|
// Location
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.Location, message.Appointment.Location);
|
|
|
|
// Start
|
|
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Appointment.Start);
|
|
|
|
// End
|
|
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Appointment.End);
|
|
|
|
// Recurrence type
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.IsRecurring,
|
|
message.Appointment.ReccurrenceType != Storage.Appointment.AppointmentRecurrenceType.None);
|
|
|
|
// Status
|
|
propertyWriter.WriteProperty(SystemProperties.System.Status, message.Appointment.ClientIntentText);
|
|
|
|
// Appointment organizer (FROM)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OrganizerAddress, message.Sender.Email);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OrganizerName, message.Sender.DisplayName);
|
|
|
|
// Mandatory participants (TO)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.RequiredAttendeeNames, message.Appointment.ToAttendees);
|
|
|
|
// Optional participants (CC)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OptionalAttendeeNames, message.Appointment.CclAttendees);
|
|
|
|
// Categories
|
|
var categories = message.Categories;
|
|
if (categories != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
|
|
|
|
// Urgent
|
|
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
|
|
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
|
|
|
|
// Attachments
|
|
var attachments = GetAttachmentNames(message);
|
|
if (string.IsNullOrEmpty(attachments))
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
|
|
}
|
|
else
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region MapTaskPropertiesToExtendedFileAttributes
|
|
/// <summary>
|
|
/// Maps all the filled <see cref="Storage.Task"/> properties to the corresponding extended file attributes
|
|
/// </summary>
|
|
/// <param name="message">The <see cref="Storage.Message"/> object</param>
|
|
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
|
|
private void MapTaskPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
|
|
{
|
|
// From
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
|
|
|
|
// Sent on
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
|
|
|
|
// Subject
|
|
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
|
|
|
|
// Task startdate
|
|
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Task.StartDate);
|
|
|
|
// Task duedate
|
|
propertyWriter.WriteProperty(SystemProperties.System.DueDate, message.Task.DueDate);
|
|
|
|
// Urgent
|
|
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
|
|
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
|
|
|
|
// Status
|
|
propertyWriter.WriteProperty(SystemProperties.System.Status, message.Task.StatusText);
|
|
|
|
// Percentage complete
|
|
propertyWriter.WriteProperty(SystemProperties.System.Task.CompletionStatus, message.Task.PercentageComplete);
|
|
|
|
// Owner
|
|
propertyWriter.WriteProperty(SystemProperties.System.Task.Owner, message.Task.Owner);
|
|
|
|
// Categories
|
|
propertyWriter.WriteProperty(SystemProperties.System.Category,
|
|
message.Categories != null ? String.Join("; ", message.Categories) : null);
|
|
|
|
// Companies
|
|
propertyWriter.WriteProperty(SystemProperties.System.Company,
|
|
message.Task.Companies != null ? String.Join("; ", message.Task.Companies) : null);
|
|
|
|
// Billing information
|
|
propertyWriter.WriteProperty(SystemProperties.System.Task.BillingInformation, message.Task.BillingInformation);
|
|
|
|
// Mileage
|
|
propertyWriter.WriteProperty(SystemProperties.System.MileageInformation, message.Task.Mileage);
|
|
|
|
// Attachments
|
|
var attachments = GetAttachmentNames(message);
|
|
if (string.IsNullOrEmpty(attachments))
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
|
|
}
|
|
else
|
|
{
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region MapContactPropertiesToExtendedFileAttributes
|
|
/// <summary>
|
|
/// Maps all the filled <see cref="Storage.Task"/> properties to the corresponding extended file attributes
|
|
/// </summary>
|
|
/// <param name="message">The <see cref="Storage.Message"/> object</param>
|
|
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
|
|
private void MapContactPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
|
|
{
|
|
// From
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
|
|
|
|
// Sent on
|
|
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
|
|
|
|
// Full name
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.FullName, message.Contact.DisplayName);
|
|
|
|
// Last name
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.LastName, message.Contact.SurName);
|
|
|
|
// First name
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.FirstName, message.Contact.GivenName);
|
|
|
|
// Job title
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.JobTitle, message.Contact.Function);
|
|
|
|
// Department
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.Department, message.Contact.Department);
|
|
|
|
// Company
|
|
propertyWriter.WriteProperty(SystemProperties.System.Company, message.Contact.Company);
|
|
|
|
// Business address
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessAddress, message.Contact.WorkAddress);
|
|
|
|
// Home address
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeAddress, message.Contact.HomeAddress);
|
|
|
|
// Other address
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.OtherAddress, message.Contact.OtherAddress);
|
|
|
|
// Instant messaging
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.IMAddress, message.Contact.InstantMessagingAddress);
|
|
|
|
// Business telephone number
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessTelephone, message.Contact.BusinessTelephoneNumber);
|
|
|
|
// Assistant's telephone number
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.AssistantTelephone, message.Contact.AssistantTelephoneNumber);
|
|
|
|
// Company main phone
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.CompanyMainTelephone, message.Contact.CompanyMainTelephoneNumber);
|
|
|
|
// Home telephone number
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeTelephone, message.Contact.HomeTelephoneNumber);
|
|
|
|
// Mobile phone
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.MobileTelephone, message.Contact.CellularTelephoneNumber);
|
|
|
|
// Car phone
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.CarTelephone, message.Contact.CarTelephoneNumber);
|
|
|
|
// Callback
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.CallbackTelephone, message.Contact.CallbackTelephoneNumber);
|
|
|
|
// Primary telephone number
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.PrimaryTelephone, message.Contact.PrimaryTelephoneNumber);
|
|
|
|
// Telex
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.TelexNumber, message.Contact.TelexNumber);
|
|
|
|
// TTY/TDD phone
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.TTYTDDTelephone, message.Contact.TextTelephone);
|
|
|
|
// Business fax
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessFaxNumber, message.Contact.BusinessFaxNumber);
|
|
|
|
// Home fax
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeFaxNumber, message.Contact.HomeFaxNumber);
|
|
|
|
// E-mail
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress, message.Contact.Email1EmailAddress);
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailName, message.Contact.Email1DisplayName);
|
|
|
|
// E-mail 2
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress2, message.Contact.Email2EmailAddress);
|
|
|
|
// E-mail 3
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress3, message.Contact.Email3EmailAddress);
|
|
|
|
// Birthday
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.Birthday, message.Contact.Birthday);
|
|
|
|
// Anniversary
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.Anniversary, message.Contact.WeddingAnniversary);
|
|
|
|
// Spouse/Partner
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.SpouseName, message.Contact.SpouseName);
|
|
|
|
// Profession
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.Profession, message.Contact.Profession);
|
|
|
|
// Assistant
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.AssistantName, message.Contact.AssistantName);
|
|
|
|
// Web page
|
|
propertyWriter.WriteProperty(SystemProperties.System.Contact.Webpage, message.Contact.Html);
|
|
|
|
// Categories
|
|
var categories = message.Categories;
|
|
if (categories != null)
|
|
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
|
|
}
|
|
#endregion
|
|
|
|
#region SetExtendedFileAttributesWithMsgProperties
|
|
/// <summary>
|
|
/// This function will read all the properties of an <see cref="Storage.Message"/> file and maps
|
|
/// all the properties that are filled to the extended file attributes.
|
|
/// </summary>
|
|
/// <param name="inputFile">The msg file</param>
|
|
public void SetExtendedFileAttributesWithMsgProperties(string inputFile)
|
|
{
|
|
MemoryStream memoryStream = null;
|
|
|
|
try
|
|
{
|
|
// We need to read the msg file into memory because we otherwise can't set the extended filesystem
|
|
// properties because the files is locked
|
|
memoryStream = new MemoryStream();
|
|
using (var fileStream = File.OpenRead(inputFile))
|
|
fileStream.CopyTo(memoryStream);
|
|
|
|
memoryStream.Position = 0;
|
|
|
|
using (var shellFile = ShellFile.FromFilePath(inputFile))
|
|
{
|
|
using (var propertyWriter = shellFile.Properties.GetPropertyWriter())
|
|
{
|
|
using (var message = new Storage.Message(memoryStream))
|
|
{
|
|
switch (message.Type)
|
|
{
|
|
case Storage.Message.MessageType.Email:
|
|
MapEmailPropertiesToExtendedFileAttributes(message, propertyWriter);
|
|
break;
|
|
|
|
case Storage.Message.MessageType.AppointmentRequest:
|
|
case Storage.Message.MessageType.Appointment:
|
|
case Storage.Message.MessageType.AppointmentResponse:
|
|
MapAppointmentPropertiesToExtendedFileAttributes(message, propertyWriter);
|
|
break;
|
|
|
|
case Storage.Message.MessageType.Task:
|
|
case Storage.Message.MessageType.TaskRequestAccept:
|
|
MapTaskPropertiesToExtendedFileAttributes(message, propertyWriter);
|
|
break;
|
|
|
|
case Storage.Message.MessageType.Contact:
|
|
MapContactPropertiesToExtendedFileAttributes(message, propertyWriter);
|
|
break;
|
|
|
|
case Storage.Message.MessageType.Unknown:
|
|
throw new NotSupportedException("Unsupported message type");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (memoryStream != null)
|
|
memoryStream.Dispose();
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|