// Spludlow Software
// Copyright © Samuel P. Ludlow 2020 All Rights Reserved
// Distributed under the terms of the GNU General Public License version 3
// Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
// https://www.spludlow.co.uk/LICENCE.TXT
// The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission
// v1.14
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Net;
using System.IO;
using System.Net.Http;
using Microsoft.Exchange.WebServices.Data;
namespace Spludlow
{
///
/// Help for EWS Microsoft.Exchange.WebServices
///
/// VERY ROUGH CODE !!! Likly to change alot
///
public class Exchange
{
public ExchangeService ExchangeService;
private string HostAddress;
private string Version;
private NetworkCredential NetworkCredential;
private ExchangeTraceListener ExchangeTraceListener;
public Exchange(string hostAddress, string userName, string password, string domain, string version)
{
NetworkCredential networkCredential = new NetworkCredential(userName, password, domain);
this.Construct(hostAddress, networkCredential, version);
}
public Exchange(string hostAddress, NetworkCredential networkCredential, string version)
{
this.Construct(hostAddress, networkCredential, version);
}
public void Reset()
{
this.Construct(this.HostAddress, this.NetworkCredential, this.Version);
}
public void Construct(string hostAddress, NetworkCredential networkCredential, string version)
{
this.HostAddress = hostAddress;
this.NetworkCredential = networkCredential;
this.Version = version;
string url = "https://" + this.HostAddress + "/EWS/Exchange.asmx";
ExchangeVersion exchangeVersion = (ExchangeVersion)Enum.Parse(typeof(ExchangeVersion), this.Version);
this.ExchangeService = new ExchangeService(exchangeVersion);
this.ExchangeService.Credentials = this.NetworkCredential;
this.ExchangeService.Url = new Uri(url);
Spludlow.WebServices.SetServerCertificateValidation();
}
public void EnableTrace(bool response, bool request)
{
TraceFlags flags = TraceFlags.None;
if (response == true)
flags |= TraceFlags.EwsResponse;
if (request == true)
flags |= TraceFlags.EwsRequest;
this.ExchangeTraceListener = new ExchangeTraceListener();
this.ExchangeService.TraceListener = this.ExchangeTraceListener;
this.ExchangeService.TraceFlags = flags;
this.ExchangeService.TraceEnabled = true;
}
public void DisableTrace()
{
this.ExchangeService.TraceEnabled = false;
}
public static void TidyXMLNames(DataSet dataSet)
{
DataSet renameDataSet = Spludlow.Data.ADO.RenameTablesAndColumnsTemplate(dataSet);
int index;
foreach (DataRow row in renameDataSet.Tables["TableNames"].Rows)
{
string name = (string)row["SourceTableName"];
while ((index = name.IndexOf(":")) != -1)
name = name.Substring(0, index - 1) + name.Substring(index + 1);
//name = name.Replace(Spludlow.Data.XML.RelationDelimiter, "");
row["TargetTableName"] = name;
}
foreach (DataRow row in renameDataSet.Tables["ColumnNames"].Rows)
{
string name = (string)row["SourceColumnName"];
while ((index = name.IndexOf(":")) != -1)
name = name.Substring(0, index - 1) + name.Substring(index + 1);
//name = name.Replace(Spludlow.Data.XML.RelationDelimiter, "");
//name = name.Replace(Spludlow.Data.XML.ID_Suffix, "_Id");
row["TargetColumnName"] = name;
}
Spludlow.Data.ADO.RenameTablesAndColumns(dataSet, renameDataSet);
}
public static void RelationizeXmlToDatabaseContacts(string xmlFilename, string connectionString, string databaseName, string databaseBackupDirectory)
{
RelationizeXmlToDatabase(xmlFilename, "t:Contact", connectionString, databaseName, databaseBackupDirectory);
}
public static void RelationizeXmlToDatabase(string xmlFilename, string topElementname, string connectionString, string databaseName, string databaseBackupDirectory)
{
DataSet dataSet = Spludlow.Data.XML.ConvertRelational(xmlFilename, topElementname);
Spludlow.Exchange.TidyXMLNames(dataSet);
DataSet schema = Spludlow.Data.ADO.Schema(dataSet, true);
// Fix Empty strings for schema lengths
foreach (DataTable table in schema.Tables)
{
if (table.TableName.EndsWith("_Columns") == false)
continue;
foreach (DataRow row in table.Select("Longest = 0"))
row["Longest"] = 1;
}
Spludlow.Data.Database.AutoAddForeignKeys(schema);
Spludlow.Log.Report("RelationizeXmlToDatabase Schema: " + topElementname, schema);
Spludlow.Data.Database.ImportDatabaseUsingTemp(schema, dataSet, connectionString, databaseName, databaseBackupDirectory);
}
public static string PostEWS(string hostAddress, NetworkCredential networkCredential, string xml)
{
// Using spludlow HTTP client dont like !!!!!!!!
//request.AllowWriteStreamBuffering = false; // Otherwise will hog memory in client EWS does not like !!!!!!!!!!!!!
//request.SendChunked = true;
string url = "https://" + hostAddress + "/EWS/Exchange.asmx";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = networkCredential;
request.Method = "POST";
request.ContentType = "text/xml";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream(), Encoding.UTF8))
writer.Write(xml);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
//Spludlow.Net.Http.WebResponseInfo info = Spludlow.Net.Http.PostText(url, xml, "text/xml", null, networkCredential, null, null, Encoding.UTF8);
//return info.Text;
}
public string UniqueFolderIdPrivateRoot()
{
return this.UniqueFolderId(WellKnownFolderName.Root);
}
public string UniqueFolderIdPublicRoot()
{
return this.UniqueFolderId(WellKnownFolderName.PublicFoldersRoot);
}
public string UniqueFolderId(WellKnownFolderName wellKnownFolderName)
{
Folder folder = Folder.Bind(this.ExchangeService, wellKnownFolderName, this.PropertySetIdOnly);
return folder.Id.UniqueId;
}
public string MailBoxRootUniqueFolderId(string userEmailAddress)
{
Mailbox mailbox = new Mailbox(userEmailAddress);
FolderId folderId = new FolderId(WellKnownFolderName.Root, mailbox);
Folder folder = Folder.Bind(this.ExchangeService, folderId, this.PropertySetIdOnly);
return folder.Id.UniqueId;
}
public void ExportItem2(string itemId, string filename, string host, string templateFilename, string exchangeVersion)
{
string template = File.ReadAllText(templateFilename, Encoding.UTF8);
StringBuilder text = new StringBuilder(template);
text.Replace("@ExchangeVersion", exchangeVersion);
text.Replace("@ItemId", itemId);
string xml = text.ToString();
File.WriteAllText(filename + ".send.xml.txt", xml);
string result = PostEWS(host, this.NetworkCredential, xml);
File.WriteAllText(filename + ".result.xml.txt", result);
}
public void ImportMessage(string filename, string targetFolderId, Spludlow.Exchange exchange)
{
//Spludlow.Email.CDOSYS.ReadMessage(filename);
}
public void ImportMessageOLD(string filename, string targetFolderId, Spludlow.Exchange exchange, string sourceItemId, string createNewFilename, string exchangeVersion, string postAddress)
{
EmailMessage sourceMessage = EmailMessage.Bind(exchange.ExchangeService, sourceItemId);
byte[] data = File.ReadAllBytes(filename);
string base64data = Convert.ToBase64String(data);
StringBuilder clean = new StringBuilder();
using (StringReader reader = new StringReader(base64data))
{
int lineSize = 55;
char[] buffer = new char[lineSize];
int count;
while ((count = reader.Read(buffer, 0, lineSize)) > 0)
{
clean.Append(buffer, 0, count);
clean.AppendLine();
}
}
base64data = clean.ToString();
File.WriteAllBytes(filename + ".back.dat", Convert.FromBase64String(base64data));
File.WriteAllText(filename + ".txt", base64data);
string template = File.ReadAllText(createNewFilename, Encoding.UTF8);
StringBuilder text = new StringBuilder(template);
text.Replace("@ExchangeVersion", exchangeVersion);
text.Replace("@Id", targetFolderId);
text.Replace("@ChangeKey", sourceMessage.Id.ChangeKey);
text.Replace("@Data", ""); //base64data);
string xml = text.ToString();
File.WriteAllText(filename + ".xml.txt", xml);
string result = PostEWS(postAddress, this.NetworkCredential, xml);
Spludlow.Log.Report("EWS", result);
}
public string CreateFolder(string parentFolderId, string name)
{
Folder folder = new Folder(this.ExchangeService);
folder.DisplayName = name;
folder.Save(new FolderId(parentFolderId));
return folder.Id.UniqueId;
}
public void CreateFolder(string folderPath)
{
int index = folderPath.LastIndexOf("/");
string parentFolder = folderPath.Substring(0, index);
string folderName = folderPath.Substring(index + 1);
// /Top of Information Store
string rootFolderId = this.UniqueFolderId(WellKnownFolderName.Root); // Slow !!!
DataTable table = this.QueryFolders(rootFolderId).Tables[0];
DataRow[] rows = table.Select("Path = '" + parentFolder + "'");
if (rows.Length > 1)
throw new ApplicationException("Exchange, CreateFolder; Found multiple parent paths for: " + folderPath);
if (rows.Length == 0)
throw new ApplicationException("Exchange, CreateFolder; Did not find parent for: " + folderPath);
string parentId = (string)rows[0]["UniqueId"];
Folder folder = new Folder(this.ExchangeService);
folder.DisplayName = folderName;
folder.Save(new FolderId(parentId));
}
public void RenameFolder(string folderId, string name)
{
FolderId id = new FolderId(folderId);
Folder folder = Folder.Bind(this.ExchangeService, id);
folder.DisplayName = name;
folder.Update();
}
public void CreateItem(Spludlow.Email.SimpleMailMessage message, string targetFolderId)
{
EmailMessage exchangeMessage = new EmailMessage(this.ExchangeService);
exchangeMessage.Subject = message.Subject;
if (message.HTMLBody.Length > 0)
exchangeMessage.Body = new MessageBody(BodyType.HTML, message.HTMLBody);
else
exchangeMessage.Body = new MessageBody(BodyType.Text, message.TextBody);
if (message.FromAddress != null)
{
exchangeMessage.From = new EmailAddress(message.FromAddress[0][1], message.FromAddress[0][0]);
}
foreach (string[] toAddress in message.ToAddress)
exchangeMessage.ToRecipients.Add(toAddress[1], toAddress[0]);
foreach (string[] replyToAddress in message.ReplyToAddress)
exchangeMessage.ReplyTo.Add(replyToAddress[1], replyToAddress[0]);
foreach (string[] attachment in message.Attachments)
{
// // Attachments [0] = Store Filename, [1] Filename, [2] = MIME
string tempFilename = attachment[0];
string filename = attachment[1];
string contentMediaType = attachment[2];
byte[] data = null;
try
{
data = File.ReadAllBytes(tempFilename);
}
catch (IOException ee)
{
if ((uint)ee.HResult != 0x800700E1)
throw ee;
Spludlow.Log.Warning(tempFilename + ", " + filename, ee);
}
if (data == null)
continue;
FileAttachment exchangeAttachment = exchangeMessage.Attachments.AddFileAttachment(filename, data);
exchangeAttachment.ContentType = contentMediaType;
if (filename.StartsWith("cid:") == true)
{
exchangeAttachment.Name = filename.Substring(4);
exchangeAttachment.IsInline = true;
exchangeAttachment.ContentId = filename;
}
else
{
exchangeAttachment.Name = filename;
}
}
if (message.ReceivedTime == DateTime.MinValue)
message.ReceivedTime = message.SentOn;
// PR_CLIENT_SUBMIT_TIME
if (message.SentOn != DateTime.MinValue)
exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(57, MapiPropertyType.SystemTime), message.SentOn.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
// PR_MESSAGE_DELIVERY_TIME
if (message.ReceivedTime != DateTime.MinValue)
exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(3590, MapiPropertyType.SystemTime), message.ReceivedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
// #define PR_MESSAGE_FLAGS PROP_TAG( PT_LONG, 0x0E07)
exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer), "1"); // Not Draft
exchangeMessage.Save(targetFolderId);
}
public static int[] MAPITagSysTimes()
{
string[] headerData = new string[]
{
"PR_DEFERRED_DELIVERY_TIME 0x000F",
"PR_DELIVER_TIME 0x0010",
"PR_EXPIRY_TIME 0x0015",
"PR_LATEST_DELIVERY_TIME 0x0019",
"PR_RECEIPT_TIME 0x002A",
"PR_REPLY_TIME 0x0030",
"PR_REPORT_TIME 0x0032",
"PR_CLIENT_SUBMIT_TIME 0x0039",
"PR_PROVIDER_SUBMIT_TIME 0x0048",
"PR_ORIGINAL_SUBMIT_TIME 0x004E",
"PR_ORIGINAL_DELIVERY_TIME 0x0055",
"PR_START_DATE 0x0060",
"PR_END_DATE 0x0061",
"PR_MESSAGE_DELIVERY_TIME 0x0E06",
"PR_CREATION_TIME 0x3007",
"PR_LAST_MODIFICATION_TIME 0x3008",
"PR_WEDDING_ANNIVERSARY 0x3A41",
"PR_BIRTHDAY 0x3A42",
};
List values = new List();
foreach (string line in headerData)
{
string[] parts = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
values.Add(Int32.Parse(parts[1].Substring(2), System.Globalization.NumberStyles.HexNumber));
}
return values.ToArray();
}
private static Guid StickyNotePropertySetId = new Guid("0006200E-0000-0000-C000-000000000046");
private static ExtendedPropertyDefinition PropertyStickyNoteColour = new ExtendedPropertyDefinition(StickyNotePropertySetId, 0x8B00, MapiPropertyType.Integer);
//#define olBlue 0
//#define olGreen 1
//#define olPink 2
//#define olYellow 3
//#define olWhite 4
public void CreateNote(string subject, string textBody, string targetFolderId)
{
EmailMessage exchangeMessage = new EmailMessage(this.ExchangeService);
exchangeMessage.ItemClass = "IPM.StickyNote";
exchangeMessage.Subject = subject;
exchangeMessage.Body = new MessageBody(BodyType.Text, textBody);
////exchangeMessage.DateTimeCreated;
////exchangeMessage.DateTimeReceived;
////exchangeMessage.DateTimeSent;
////// #define PR_CLIENT_SUBMIT_TIME PROP_TAG( PT_SYSTIME, 0x0039)
////exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(0x0039, MapiPropertyType.SystemTime), dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
////// #define PR_MESSAGE_DELIVERY_TIME PROP_TAG( PT_SYSTIME, 0x0E06)
////exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(0x0E06, MapiPropertyType.SystemTime), dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
//foreach (int tagId in MAPITagSysTimes())
// exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(tagId, MapiPropertyType.SystemTime), dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
////
////exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(3590, MapiPropertyType.SystemTime), dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
// #define PR_MESSAGE_FLAGS PROP_TAG( PT_LONG, 0x0E07)
//exchangeMessage.SetExtendedProperty(new ExtendedPropertyDefinition(0x0E07, MapiPropertyType.Integer), "1"); // Not Draft
exchangeMessage.SetExtendedProperty(PropertyStickyNoteColour, 3); // Yellow
exchangeMessage.Save(targetFolderId);
}
public void ExportCalendarFolder(string topFolderId, string exportDirectory, bool delete, bool hardDelete)
{
DataTable itemsTable = this.QueryCalendarFolder(topFolderId).Tables[0];
DataRow[] rows = itemsTable.Select("Keep = True");
if (rows.Length == 0)
{
Directory.Delete(exportDirectory, true);
return;
}
foreach (DataRow itemRow in rows)
{
// "UniqueId DateTimeReceived Size Subject AppointmentType DateTimeCreated Start End Keep",
string itemUniqueId = (string)itemRow["UniqueId"];
string subject = (string)itemRow["Subject"];
DateTime dateTimeReceived = (DateTime)itemRow["DateTimeReceived"];
string filename = exportDirectory + @"\" + Spludlow.Text.TimeStamp(dateTimeReceived) + "_" + subject.Trim();
this.ExportItem(itemUniqueId, filename); // will add extention !!!! .xml
}
}
public void ImportCalendarFolder(string targetFolderId, string sourceDirectory)
{
CalendarFolder folder = CalendarFolder.Bind(this.ExchangeService, targetFolderId);
foreach (string filename in Directory.GetFiles(sourceDirectory, "*.ics"))
{
Appointment appointment = new Appointment(this.ExchangeService);
appointment.MimeContent = new MimeContent("UTF-8", File.ReadAllBytes(filename));
appointment.Save(folder.Id);
}
}
public void TestCreateContact(string targetFolderId, string sendXmlFilename, string serverAddress)
{
string send = File.ReadAllText(sendXmlFilename, Encoding.UTF8);
string result = PostEWS(serverAddress, this.NetworkCredential, send);
Spludlow.Log.Report("XML Result", result);
}
public void ExportContactsFolder(string topFolderId, string exportDirectory, bool delete, bool hardDelete)
{
DataTable itemsTable = this.QueryContactsFolder(topFolderId).Tables[0];
foreach (DataRow itemRow in itemsTable.Rows)
{
// "UniqueId DateTimeReceived Size Subject",
string itemUniqueId = (string)itemRow["UniqueId"];
string subject = (string)itemRow["Subject"];
DateTime dateTimeReceived = (DateTime)itemRow["DateTimeReceived"];
string filename = exportDirectory + @"\" + Spludlow.Text.TimeStamp(dateTimeReceived) + "_" + subject.Trim();
this.ExportItem(itemUniqueId, filename); // will add extention !!!! .xml
}
Spludlow.Log.Report("ExportContactsFolder", itemsTable);
}
public void ExportContacts(string folderId, string exportFilename)
{
// seems to break at 8192
int pageSize = 4096;
int offset = 0;
bool more = true;
ContactsFolder folder = ContactsFolder.Bind(this.ExchangeService, folderId);
int extentionIndex = exportFilename.LastIndexOf(".");
while (more == true)
{
ItemView itemView = new ItemView(pageSize, offset * pageSize);
itemView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
this.ExchangeService.TraceEnabled = true;
try
{
this.ExchangeTraceListener.Reset();
FindItemsResults- items = folder.FindItems(itemView);
string[] result = this.ExchangeTraceListener.Read();
if (result.Length != 1)
throw new ApplicationException("Did not trace 1 result: " + result.Length);
string pageFilename = exportFilename.Substring(0, extentionIndex) + "." + offset.ToString() + exportFilename.Substring(extentionIndex);
if (items.TotalCount > 0)
File.WriteAllText(pageFilename, result[0], Encoding.UTF8);
more = items.MoreAvailable;
++offset;
}
finally
{
this.ExchangeService.TraceEnabled = false;
}
}
}
public void ExportContactsIndividual(string folderId, string directory, string exportFilename)
{
// seems to break at 8192
int pageSize = 4096;
int offset = 0;
bool more = true;
ContactsFolder folder = ContactsFolder.Bind(this.ExchangeService, folderId);
int extentionIndex = exportFilename.LastIndexOf(".");
while (more == true)
{
ItemView itemView = new ItemView(pageSize, offset * pageSize);
itemView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
this.ExchangeService.TraceEnabled = true;
try
{
this.ExchangeTraceListener.Reset();
FindItemsResults
- items = folder.FindItems(itemView);
string[] result = this.ExchangeTraceListener.Read();
if (result.Length != 1)
throw new ApplicationException("Did not trace 1 result: " + result.Length);
string pageFilename = exportFilename.Substring(0, extentionIndex) + "." + offset.ToString() + exportFilename.Substring(extentionIndex);
if (items.TotalCount > 0)
File.WriteAllText(pageFilename, result[0], Encoding.UTF8);
more = items.MoreAvailable;
++offset;
}
finally
{
this.ExchangeService.TraceEnabled = false;
}
}
}
public void ExportContacts2(string folderId, string directory)
{
// MIME conversion is not supported for this item type. contact.MimeContent.Content, ContactSchema.MimeContent Contact & Item ItemSchema.MimeContent
// old verison of exchange
DataTable table = this.QueryItems(folderId).Tables[0];
foreach (DataRow row in table.Rows)
{
string itemId = (string)row["UniqueId"];
Contact contact = Contact.Bind(this.ExchangeService, itemId);
PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties, ContactSchema.Body); //.FirstClassProperties, ItemSchema.Body);
//propertySet.RequestedBodyType = BodyType.Text;
contact.Load(propertySet);
EmailMessage message = new EmailMessage(this.ExchangeService);
ItemAttachment itemAttachment = message.Attachments.AddItemAttachment();
}
}
// Notes does not have own folder type
// Task does !!!
public void ExportItemsBatchXML(string folderId, string exportFilename) // change !!!! same as above ?? folder type
{
// seems to break at 8192
int pageSize = 4096;
int offset = 0;
bool more = true;
Folder folder = Folder.Bind(this.ExchangeService, folderId);
int extentionIndex = exportFilename.LastIndexOf(".");
while (more == true)
{
ItemView itemView = new ItemView(pageSize, offset * pageSize);
itemView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties); //, EmailMessageSchema.Body);
itemView.PropertySet.RequestedBodyType = BodyType.Text; // note
this.ExchangeService.TraceEnabled = true;
try
{
this.ExchangeTraceListener.Reset();
FindItemsResults
- items = folder.FindItems(itemView);
string[] result = this.ExchangeTraceListener.Read();
if (result.Length != 1)
throw new ApplicationException("Did not trace 1 result: " + result.Length);
string pageFilename = exportFilename.Substring(0, extentionIndex) + "." + offset.ToString() + exportFilename.Substring(extentionIndex);
if (items.TotalCount > 0)
File.WriteAllText(pageFilename, result[0], Encoding.UTF8);
more = items.MoreAvailable;
++offset;
}
finally
{
this.ExchangeService.TraceEnabled = false;
}
}
}
public void ExportNotes(string folderId, string targetDirectory)
{
DataTable table = this.QueryItems(folderId).Tables[0];
if (table.Rows.Count == 0)
{
Directory.Delete(targetDirectory, true);
return;
}
foreach (DataRow row in table.Rows)
{
string itemId = (string)row["UniqueId"];
Item item = Item.Bind(this.ExchangeService, itemId);
PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Body);
propertySet.RequestedBodyType = BodyType.Text;
this.ExchangeService.TraceEnabled = true;
try
{
this.ExchangeTraceListener.Reset();
item.Load(propertySet);
string[] result = this.ExchangeTraceListener.Read();
if (result.Length != 1)
throw new ApplicationException("Did not trace 1 result: " + result.Length);
string subject = item.Subject;
if (subject == null)
subject = "";
string filename = targetDirectory + @"\" + Spludlow.Text.TimeStamp(item.DateTimeReceived) + "_" + Spludlow.Io.Paths.LegalFileName(subject) + ".xml";
if (item.ItemClass == "IPM.StickyNote")
File.WriteAllText(filename, result[0], Encoding.UTF8);
else
Spludlow.Log.Warning("ExportNotes; ItemClass: " + item.ItemClass);
}
finally
{
this.ExchangeService.TraceEnabled = false;
}
}
}
public void ExportMessages(string topFolderId, string exportDirectory, DateTime beforeDate, bool delete, bool hardDelete)
{
DateTime startDate = DateTime.MinValue;
this.ExportMessages(topFolderId, exportDirectory, startDate, beforeDate, delete, hardDelete);
}
public void ExportMessages(string topFolderId, string exportDirectory, DateTime startDate, DateTime beforeDate, bool delete, bool hardDelete)
{
DataTable table = this.QueryFolders(topFolderId).Tables[0];
foreach (DataRow row in table.Rows)
{
string folderType = (string)row["FolderType"];
if (folderType != "Folder")
continue;
int totalCount = (int)row["TotalCount"];
if (totalCount == 0)
continue;
string uniqueId = (string)row["UniqueId"];
DataTable itemsTable = this.QueryMessages(uniqueId, startDate, beforeDate).Tables[0];
if (itemsTable.Rows.Count == 0)
continue;
string path = (string)row["Path"];
path = exportDirectory + path.Replace("/", @"\");
Directory.CreateDirectory(path);
foreach (DataRow itemRow in itemsTable.Rows)
{
string itemUniqueId = (string)itemRow["UniqueId"];
ItemId itemId = new ItemId(itemUniqueId);
Item item = Item.Bind(this.ExchangeService, itemId); //, this.PropertySetMimeContent);
item.Load(this.PropertySetMimeContent);
string itemTypeName = item.GetType().Name;
EmailAddress fromEmailAddress = null;
if (itemTypeName == "EmailMessage")
{
EmailMessage emailMessage = (EmailMessage)item;
fromEmailAddress = emailMessage.From;
}
if (itemTypeName == "PostItem")
{
PostItem postItem = (PostItem)item;
fromEmailAddress = postItem.From;
}
int maxLength = 32;
string subject = Spludlow.Io.Paths.LegalFileName((string)itemRow["Subject"]);
if (subject.Length > maxLength)
subject = subject.Substring(0, maxLength);
DateTime dateTimeReceived = (DateTime)itemRow["DateTimeReceived"];
string smtpFromAddress = "";
if (fromEmailAddress != null && fromEmailAddress.Address != null)
{
NameResolutionCollection names = this.ExchangeService.ResolveName(fromEmailAddress.Address);
if (names.Count > 0)
smtpFromAddress = names[0].Mailbox.Address;
else
smtpFromAddress = fromEmailAddress.Name;
}
maxLength = 48;
string fromAddress = Spludlow.Io.Paths.LegalFileName(smtpFromAddress);
if (fromAddress.Length > maxLength)
fromAddress = fromAddress.Substring(0, maxLength);
string filename = Spludlow.Text.TimeStamp(dateTimeReceived) + "_" + subject + "_" + fromAddress + ".EML";
itemRow["Filename"] = filename;
File.WriteAllBytes(path + @"\" + filename, item.MimeContent.Content);
if (fromEmailAddress != null)
{
itemRow["FromDisplay"] = fromEmailAddress.Name;
itemRow["FromAddress"] = fromEmailAddress.Address;
}
}
// try finally the table
string indexPath = path + @"\_Index.txt";
Spludlow.Data.TextTable.Write(indexPath, itemsTable, Encoding.UTF8);
// Do Deletes in batches !!!!!!
if (delete == true)
{
foreach (DataRow itemRow in itemsTable.Rows)
{
string itemUniqueId = (string)itemRow["UniqueId"];
ItemId itemId = new ItemId(itemUniqueId);
Item item = Item.Bind(this.ExchangeService, itemId);
if (hardDelete == true)
item.Delete(DeleteMode.HardDelete);
else
item.Delete(DeleteMode.MoveToDeletedItems);
}
}
}
}
public void DeleteItem(string itemId, bool hardDelete)
{
ItemId id = new ItemId(itemId);
Item item = Item.Bind(this.ExchangeService, id);
if (hardDelete == true)
item.Delete(DeleteMode.HardDelete);
else
item.Delete(DeleteMode.MoveToDeletedItems);
}
public void ClearFolder(string folderId, bool hardDelete)
{
DataTable table = this.QueryItems(folderId).Tables[0];
foreach (DataRow row in table.Rows)
{
string itemId = (string)row["UniqueId"];
this.DeleteItem(itemId, hardDelete);
}
}
private PropertySet PropertySetMimeContent = new PropertySet(ItemSchema.MimeContent, PostItemSchema.From, EmailMessageSchema.From);
public static string[] ListWellKnownFolderNames()
{
return Enum.GetNames(typeof(WellKnownFolderName));
}
public Dictionary WellKnownFolderNameIds(string userEmailAddress)
{
string[] names = new string[]
{
"Calendar",
"Contacts",
//"DeletedItems",
"Drafts",
"Inbox",
//"Journal",
"Notes",
"Outbox",
"SentItems",
"Tasks",
//"MsgFolderRoot",
//"PublicFoldersRoot",
//"Root",
//"JunkEmail",
//"SearchFolders",
//"VoiceMail",
//"RecoverableItemsRoot",
//"RecoverableItemsDeletions",
//"RecoverableItemsVersions",
//"RecoverableItemsPurges",
//"ArchiveRoot",
//"ArchiveMsgFolderRoot",
//"ArchiveDeletedItems",
//"ArchiveRecoverableItemsRoot",
//"ArchiveRecoverableItemsDeletions",
//"ArchiveRecoverableItemsVersions",
//"ArchiveRecoverableItemsPurges",
//"SyncIssues",
//"Conflicts",
//"LocalFailures",
//"ServerFailures",
//"RecipientCache", Only valid on new servers older servers /Top of Information Store/Suggested Contacts
//"QuickContacts",
//"ConversationHistory",
//"ToDoSearch",
};
Dictionary result = new Dictionary();
Mailbox mailbox = new Mailbox(userEmailAddress);
foreach (string name in names)
{
WellKnownFolderName wellKnownFolderName = (WellKnownFolderName)Enum.Parse(typeof(WellKnownFolderName), name);
FolderId folderId = new FolderId(wellKnownFolderName, mailbox);
Folder folder = Folder.Bind(this.ExchangeService, folderId, this.PropertySetIdOnly);
result.Add(folder.Id.UniqueId, name); // ID, NAME !!!
}
return result;
}
//WellKnownFolderName.Calendar;
// WellKnownFolderName.Contacts;
// WellKnownFolderName.Drafts;
// WellKnownFolderName.Inbox;
// WellKnownFolderName.Notes;
// WellKnownFolderName.Outbox;
// WellKnownFolderName.RecipientCache;
// WellKnownFolderName.SentItems;
// WellKnownFolderName.Tasks;
public DataSet QueryFolders(string topFolderId)
{
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DisplayName Depth Path FolderType ChildFolderCount TotalCount", // iswellknows !!!
"String String Int32 String String Int32 Int32",
});
this.WalkFolders(table, topFolderId, 0, null);
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
return dataSet;
}
public DataSet Test()
{
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"Info",
"String",
});
// Root
string folderUniqueId = this.UniqueFolderId(WellKnownFolderName.Root);
FolderId folderId = new FolderId(folderUniqueId);
Folder folder = Folder.Bind(this.ExchangeService, folderId, new PropertySet(BasePropertySet.IdOnly));
PropertySet set = new PropertySet(FolderSchema.Id, FolderSchema.DisplayName, FolderSchema.ChildFolderCount, FolderSchema.TotalCount);
folder.Load(set);
table.Rows.Add(folderUniqueId);
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
return dataSet;
}
private void WalkFolders(DataTable table, string folderUniqueId, int depth, string path)
{
FolderId folderId = new FolderId(folderUniqueId);
Folder folder;
try
{
folder = Folder.Bind(this.ExchangeService, folderId, new PropertySet(BasePropertySet.IdOnly));
}
catch (Exception ee)
{
Spludlow.Log.Warning("WalkFolders: " + folderUniqueId, ee);
return;
}
PropertySet set = new PropertySet(FolderSchema.Id, FolderSchema.DisplayName, FolderSchema.ChildFolderCount, FolderSchema.TotalCount);
folder.Load(set);
string displayPath = "";
if (folder.DisplayName != null)
displayPath = Spludlow.Io.Paths.LegalFileName(folder.DisplayName);
if (depth == 0)
{
path = "/";
}
else
{
if (depth == 1)
path = "/" + displayPath;
else
path = path + "/" + displayPath;
}
table.Rows.Add(folder.Id.UniqueId, folder.DisplayName, depth, path, folder.GetType().Name, folder.ChildFolderCount, folder.TotalCount);
//folder.ManagedFolderInformation
FolderView view = new FolderView(Int32.MaxValue);
FindFoldersResults results = folder.FindFolders(view);
foreach (Folder subFolder in results.Folders)
this.WalkFolders(table, subFolder.Id.UniqueId, depth + 1, path);
}
public DataSet QueryMessages(string folderUniqueId, DateTime startDate, DateTime beforeEndDate)
{
int pageSzie = Int32.MaxValue;
int pageIndex = 0;
FolderId folderId = new FolderId(folderUniqueId);
Folder folder = Folder.Bind(this.ExchangeService, folderId);
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DateTimeReceived Size Subject ItemType FromDisplay FromAddress Filename",
"String DateTime Int32 String String String String String",
});
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
ItemView itemView = new ItemView(pageSzie, pageIndex);
itemView.PropertySet = new PropertySet(ItemSchema.DateTimeReceived, ItemSchema.Size, ItemSchema.Subject); // need to load for this will take too long here, EmailMessageSchema.From); // from for mail !!!
SearchFilter.SearchFilterCollection searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And);
if (startDate != DateTime.MinValue)
searchFilter.Add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, startDate));
if (beforeEndDate != DateTime.MaxValue)
searchFilter.Add(new SearchFilter.IsLessThan(ItemSchema.DateTimeReceived, beforeEndDate));
if (searchFilter.Count == 0)
searchFilter = null;
itemView.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Ascending);
itemView.OrderBy.Add(ItemSchema.Subject, SortDirection.Ascending);
FindItemsResults
- findResults = folder.FindItems(searchFilter, itemView);
foreach (Item item in findResults.Items)
{
string itemType = item.GetType().Name;
if (itemType != "EmailMessage" && itemType != "PostItem")
continue;
string subject = item.Subject;
if (subject == null)
subject = "";
table.Rows.Add(item.Id.UniqueId, item.DateTimeReceived, item.Size, subject, itemType, null, null, null);
}
return dataSet;
}
public DataSet QueryItems(string folderUniqueId)
{
int pageSzie = Int32.MaxValue;
int pageIndex = 0;
FolderId folderId = new FolderId(folderUniqueId);
Folder folder = Folder.Bind(this.ExchangeService, folderId);
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DateTimeReceived Size Subject ItemType FromDisplay FromAddress Filename",
"String DateTime Int32 String String String String String",
});
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
ItemView itemView = new ItemView(pageSzie, pageIndex);
itemView.PropertySet = new PropertySet(ItemSchema.DateTimeReceived, ItemSchema.Size, ItemSchema.Subject); // need to load for this will take too long here, EmailMessageSchema.From); // from for mail !!!
SearchFilter.SearchFilterCollection searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And);
//if (startDate != DateTime.MinValue)
// searchFilter.Add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, startDate));
//if (beforeEndDate != DateTime.MaxValue)
// searchFilter.Add(new SearchFilter.IsLessThan(ItemSchema.DateTimeReceived, beforeEndDate));
if (searchFilter.Count == 0)
searchFilter = null;
itemView.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Ascending);
itemView.OrderBy.Add(ItemSchema.Subject, SortDirection.Ascending);
FindItemsResults
- findResults = folder.FindItems(searchFilter, itemView);
foreach (Item item in findResults.Items)
{
string itemType = item.GetType().Name;
//if (itemType != "EmailMessage" && itemType != "PostItem")
// continue;
string subject = item.Subject;
if (subject == null)
subject = "";
table.Rows.Add(item.Id.UniqueId, item.DateTimeReceived, item.Size, subject, itemType, null, null, null);
}
return dataSet;
}
public DataSet QueryCalendarFolder(string folderId)
{
DateTime startDate = new DateTime(2000, 1, 1);
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DateTimeReceived Size Subject AppointmentType DateTimeCreated Start End Keep",
"String DateTime Int32 String String DateTime DateTime DateTime Boolean",
});
// Note that recurring master calendar items aren't returned in a call to FindAppointments. If you want to retrieve recurring masters, or you want a more general approach to retrieving calendar items, you need to use ExchangeService.FindItems.
CalendarFolder folder = CalendarFolder.Bind(this.ExchangeService, folderId);
SearchFilter.SearchFilterCollection searchFilter = new SearchFilter.SearchFilterCollection();
searchFilter.Add(new SearchFilter.IsGreaterThanOrEqualTo(AppointmentSchema.Start, startDate));
ItemView itemView = new ItemView(Int32.MaxValue);
itemView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
FindItemsResults
- findResults = this.ExchangeService.FindItems(folder.Id, searchFilter, itemView);
foreach (Appointment item in findResults.Items)
{
string subject = item.Subject;
if (subject == null)
subject = "";
bool keep = true;
if (item.AppointmentType == AppointmentType.Single && item.End < DateTime.Now)
keep = false;
table.Rows.Add(item.Id.UniqueId, item.DateTimeReceived, item.Size, subject, item.AppointmentType.ToString(), item.DateTimeCreated, item.Start, item.End, keep);
}
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
return dataSet;
}
public DataSet QueryContactsFolder(string folderId)
{
DataTable table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DateTimeReceived Size Subject",
"String DateTime Int32 String",
});
ContactsFolder folder = ContactsFolder.Bind(this.ExchangeService, folderId);
ItemView itemView = new ItemView(Int32.MaxValue, 0);
FindItemsResults
- items = folder.FindItems(itemView);
foreach (Item item in items)
{
Contact contact = Contact.Bind(this.ExchangeService, item.Id, PropertySetFirstClassProperties);
string subject = contact.Subject;
if (subject == null)
subject = "";
table.Rows.Add(contact.Id.UniqueId, contact.DateTimeReceived, contact.Size, subject);
}
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
return dataSet;
}
private PropertySet PropertySetIdOnly = new PropertySet(BasePropertySet.IdOnly);
private PropertySet PropertySetFirstClassProperties = new PropertySet(BasePropertySet.FirstClassProperties);
private PropertySet PropertySetAppointmentSchemaMimeContent = new PropertySet(AppointmentSchema.MimeContent);
private PropertySet PropertySetContactSchemaSchemaMimeContent = new PropertySet(ContactSchema.MimeContent);
public void ExportItem(string uniqueId, string filename)
{
Item item = Item.Bind(this.ExchangeService, uniqueId);
string itemTypeName = item.GetType().Name;
if (itemTypeName == "Appointment")
{
Appointment appointment = Appointment.Bind(this.ExchangeService, item.Id);
appointment.Load(PropertySetAppointmentSchemaMimeContent);
File.WriteAllBytes(filename + ".ics", appointment.MimeContent.Content);
//appointment.LastOccurrence;
return;
}
//if (itemTypeName == "Contact")
//{
// Contact contact = Contact.Bind(this.ExchangeService, item.Id); //, PropertySetContactSchemaSchemaMimeContent);
// contact.Load(PropertySetFirstClassProperties);
// StringBuilder text = new StringBuilder();
// text.AppendLine(contact.Subject);
// text.AppendLine(contact.DateTimeReceived.ToString());
// text.AppendLine(contact.FileAs);
// text.AppendLine(contact.FileAsMapping.ToString());
// text.AppendLine(contact.DisplayName);
// text.AppendLine(contact.GivenName);
// text.AppendLine(contact.Initials);
// text.AppendLine(contact.MiddleName);
// text.AppendLine(contact.CompleteName.FullName);
// text.AppendLine(contact.CompleteName.GivenName);
// text.AppendLine(contact.CompleteName.Initials);
// text.AppendLine(contact.CompleteName.MiddleName);
// text.AppendLine(contact.CompleteName.NickName);
// text.AppendLine(contact.CompleteName.Suffix);
// text.AppendLine(contact.CompleteName.Surname);
// text.AppendLine(contact.CompleteName.Title);
// text.AppendLine(contact.CompleteName.YomiGivenName);
// text.AppendLine(contact.CompleteName.YomiSurname);
// text.AppendLine(contact.CompanyName);
// File.WriteAllText(filename + ".txt", text.ToString(), Encoding.UTF8);
// return;
//}
// contacts the vCard (.vcf)
if (itemTypeName == "EmailMessage" || itemTypeName == "PostItem")
{
item.Load(this.PropertySetMimeContent);
File.WriteAllBytes(filename + ".EML", item.MimeContent.Content);
}
else
{
//this.ExchangeService.TraceEnabled = true;
this.EnableTrace(true, false);
try
{
this.ExchangeTraceListener.Reset();
item.Load(this.PropertySetFirstClassProperties);
string[] result = this.ExchangeTraceListener.Read();
if (result.Length != 1)
throw new ApplicationException("Did not trace 1 result: " + result.Length);
File.WriteAllText(filename + ".XML", result[0], Encoding.UTF8);
}
finally
{
//this.ExchangeService.TraceEnabled = false;
this.DisableTrace();
}
}
}
public void CopyItem(string uniqueId, string filename)
{
}
public void MirrorFolder(string folderUniqueId, string directory, int historyDays)
{
if (Directory.Exists(directory) == false)
Directory.CreateDirectory(directory);
string indexFilename = directory + @"\_Index.txt";
DataTable table;
if (File.Exists(indexFilename) == true)
{
table = Spludlow.Data.TextTable.ReadFile(indexFilename, Encoding.UTF8);
}
else
{
table = Spludlow.Data.TextTable.ReadText(new string[]
{
"UniqueId DateTimeReceived Size Subject DateTimeDownload Filename",
"String* DateTime Int32 String String String",
});
}
DateTime startDate = DateTime.Now.AddMinutes(-historyDays);
DataTable serverTable = QueryMessages(folderUniqueId, startDate, DateTime.MaxValue).Tables[0];
// Download new
int downloadCount = 0;
foreach (DataRow serverRow in serverTable.Rows)
{
string itemUniqueId = (string)serverRow["UniqueId"];
if (table.Rows.Find(itemUniqueId) != null)
continue;
ItemId itemId = new ItemId(itemUniqueId);
Item item = Item.Bind(this.ExchangeService, itemId);
item.Load(this.PropertySetMimeContent);
DateTime dateTimeReceived = (DateTime)serverRow["DateTimeReceived"];
string subject = (string)serverRow["Subject"];
string filename = directory + @"\" + Spludlow.Io.Paths.LegalFileName(Spludlow.Text.TimeStamp(dateTimeReceived) + "_" + subject + ".EML");
filename = Spludlow.Io.Files.UniqueExistingName(filename);
DataRow row = table.NewRow();
row["UniqueId"] = itemUniqueId;
row["DateTimeReceived"] = dateTimeReceived;
row["Size"] = (int)serverRow["Size"];
row["Subject"] = subject;
row["DateTimeDownload"] = DateTime.Now;
row["Filename"] = Path.GetFileName(filename);
table.Rows.Add(row);
File.WriteAllBytes(filename, item.MimeContent.Content);
++downloadCount;
}
// Delete old
int deleteCount = 0;
if (downloadCount > 0) // Only delete old when getting new? (errors above wont reach here anyway)
{
foreach (DataRow deleteRow in table.Select("DateTimeReceived < #" + Spludlow.Text.TimeStampDataTableSelect(startDate) + "#"))
deleteRow.Delete();
List existingFilenames = new List(Directory.GetFiles(directory, "*.EML"));
foreach (DataRow row in table.Rows)
{
string filename = directory + @"\" + (string)row["Filename"];
if (existingFilenames.Contains(filename) == true)
existingFilenames.Remove(filename);
}
deleteCount = existingFilenames.Count;
foreach (string filename in existingFilenames)
File.Delete(filename);
}
if (File.Exists(indexFilename) == true)
File.Delete(indexFilename);
Spludlow.Data.TextTable.Write(indexFilename, table, Encoding.UTF8);
Spludlow.Log.Report("Exchange MirrorFolder; New:" + downloadCount + ", Old:" + deleteCount, table);
}
private DataSet SearchFolderOLD(string uniqueId, string subject, DateTime receivedAfter, DateTime receivedBefore, int minSize)
{
DataSet dataSet = new DataSet();
DataTable table = new DataTable();
table.Columns.Add("UniqueId", typeof(string));
table.Columns.Add("From", typeof(string));
table.Columns.Add("Subject", typeof(string));
table.Columns.Add("DateTimeSent", typeof(DateTime));
table.Columns.Add("DateTimeReceived", typeof(DateTime));
table.Columns.Add("Size", typeof(int));
Microsoft.Exchange.WebServices.Data.ItemView itemView = new Microsoft.Exchange.WebServices.Data.ItemView(Int32.MaxValue);
itemView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Size);
SearchFilter.SearchFilterCollection searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And);
if (subject != null)
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject, subject));
if (receivedAfter != DateTime.MinValue)
searchFilterCollection.Add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, receivedAfter));
if (receivedBefore != DateTime.MaxValue)
searchFilterCollection.Add(new SearchFilter.IsLessThan(ItemSchema.DateTimeReceived, receivedBefore));
if (minSize != 0)
searchFilterCollection.Add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.Size, minSize));
Microsoft.Exchange.WebServices.Data.FindItemsResults itemResults = null;
if (uniqueId.Length < 32)
{
WellKnownFolderName folderName = (WellKnownFolderName)Enum.Parse(typeof(WellKnownFolderName), uniqueId);
if (searchFilterCollection.Count == 0)
itemResults = this.ExchangeService.FindItems(folderName, itemView);
else
itemResults = this.ExchangeService.FindItems(folderName, searchFilterCollection, itemView);
}
else
{
FolderId folderId = new FolderId(uniqueId);
if (searchFilterCollection.Count == 0)
itemResults = this.ExchangeService.FindItems(folderId, itemView);
else
itemResults = this.ExchangeService.FindItems(folderId, searchFilterCollection, itemView);
}
foreach (Microsoft.Exchange.WebServices.Data.Item item in itemResults)
{
if (item is Microsoft.Exchange.WebServices.Data.EmailMessage)
{
Microsoft.Exchange.WebServices.Data.EmailMessage emailMessage = (Microsoft.Exchange.WebServices.Data.EmailMessage)item;
string fromName = "";
if (emailMessage.From != null)
fromName = emailMessage.From.Name;
table.Rows.Add(new object[]
{
emailMessage.Id.UniqueId,
fromName,
emailMessage.Subject,
emailMessage.DateTimeSent,
emailMessage.DateTimeReceived,
emailMessage.Size
});
}
}
dataSet.Tables.Add(table);
return dataSet;
}
}
}