I have the following code that takes an email address of received email once it was selected in Outlook Explorer and tries to find other emails that were received from this address.
(I had historical reason to pass both email address and Outlook.MailItem to this function)
` public (bool, int, bool) SearchAccountForEmail(string emailAddress, MailItem receivedEmail)
{
using (Log.VerboseCall())
{
bool found = false;
int count = 0;
bool domainNotSeen = false;
Outlook.Account emailAccount = null;
Outlook.Store store = null;
Outlook.Folder rootFolder = null;
try
{
emailAccount = receivedEmail.SendUsingAccount;
Log.Verbose($"Finding {emailAddress} in account: {emailAccount}");
if (emailAccount != null)
{
// Get the root folder of the delivery store
store = emailAccount.DeliveryStore;
rootFolder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;
byte[] mailItemEntryIdBytes = (byte[])mSelectedMailItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FFF0102");
string entryId = BitConverter.ToString(mailItemEntryIdBytes).Replace("-", "");
// Search folders in this account
(found, count) = IsEmailInFolder(rootFolder, emailAddress, entryId);
Log.Verbose($"Found Total: {count} emails, in folder {rootFolder.Name} for account {emailAccount.DisplayName}");
domainNotSeen = !IsDomainInFolder(rootFolder, emailAddress);
Log.Verbose($"Did not find additional domain in folder {rootFolder.Name} in account {emailAccount.DisplayName}: {domainNotSeen.ToString()}");
}
else
{
Log.Verbose("Account not found.");
}
}
catch(Exception ex)
{
Log.Verbose(ex);
}
finally
{
if (store != null) Marshal.ReleaseComObject(store);
if (rootFolder != null) Marshal.ReleaseComObject(rootFolder);
if (emailAccount != null) Marshal .ReleaseComObject(emailAccount);
}
return (found, count, domainNotSeen);
}
}
public (bool, int) IsEmailInFolder(Outlook.Folder folder, string emailAddress, string entryId)
{
using(Log.VerboseCall())
{
string filter = $"@SQL="urn:schemas:httpmail:fromemail" = '{emailAddress}'";
string PR_LONGTERM_ENTRYID_FROM_TABLE = "http://schemas.microsoft.com/mapi/proptag/0x66700102";
Table table = null;
int rowCount = 0;
QueryResponse qm = new QueryResponse();
try
{
// Why to create Table every time we are searching for email instead of once:
// - it is different for every folder
// - the content change as new email arrive
//
// Try to retrieve a table of email items filtered by sender's email address
table = folder.GetTable(filter, OlTableContents.olUserItems);
if (table != null)
{
table.Columns.Add("SenderEmailAddress");
table.Columns.Add("http://schemas.microsoft.com/mapi/proptag/0x66700102");
rowCount = table.GetRowCount();
Log.Verbose($"Found {rowCount} number of rows in table of in {folder.Name} folder, matching email {emailAddress} .");
while (!table.EndOfTable)
{
Row row = table.GetNextRow();
if (row != null)
{
string senderEmail = row["SenderEmailAddress"].ToString();
if (String.Compare(senderEmail, emailAddress, true) == 0)
{
string hexEntryId = row.BinaryToString(PR_LONGTERM_ENTRYID_FROM_TABLE);
if (row != null)
Marshal.ReleaseComObject(row);
if (String.Compare(entryId, hexEntryId, StringComparison.OrdinalIgnoreCase) != 0)
{
Log.Verbose($"Folder: {folder.Name} - Found email with the same address {emailAddress} and different EntryID");
break;
}
}
if (row != null)
Marshal.ReleaseComObject(row);
}
}
}
}
catch (Exception ex)
{
Log.Verbose(ex);
}
finally
{
if (table != null) Marshal.ReleaseComObject(table);
}
// Reduce the count - we don't count for the message itself, only for extra once found
if (rowCount > 0)
rowCount--;
bool found = (rowCount > 0) ? true : false;
if (found == true)
{
Log.Verbose($"Folder: {folder.Name} - {rowCount} emails found with the same address {emailAddress} and differnt EntryID");
return (true, rowCount);
}
foreach (Folder subFolder in folder.Folders)
{
Log.Verbose($"Checking subFolder {subFolder.Name} for email address {emailAddress}");
(bool ret, int count) = IsEmailInFolder(subFolder, emailAddress, entryId);
if (ret == true)
{
rowCount += count;
}
}
Log.Verbose($"Folder: {folder.Name} - {rowCount} emails found with the same address {emailAddress} and differnt EntryID");
return (rowCount > 0) ? (true, rowCount) : (false, 0);
}
}
`
As you can see the job is done in IsEmailInFolder function by using DASL table.
So here is the problem:
For some email addresses it finds additional emails with the same ‘To’ address, and some emails (50%) it does not, and I have no idea why it gives me such bazaar results. Maybe DASL is not as reliable as I thought it was?
Obviously there must be at least one email with the input address – the email itself, and that’s why I use EntryID to verify that I am not taking into account the email itself. This is recursive as I go through Inbox and all of its subfolders for a particular account.
I tried different schemes and debugging – it works on my machine but only finds 50% on client’s machine.