I have an Outlook VSTO add-in and I need to determine if the Outlook.MailItem being processed corresponds to a saved file on the local disk that has been opened in Outlook, regardless of the type of account configured (Exchange, IMAP, etc.). I need to differentiate it from a draft or any other type of email in any folder which is not a saved email.
Specifically, I need to detect unequivocally whether a MailItem was saved on the local disk and then opened in Outlook so that I can perform certain actions.
Here is a combination of things I have tried without success:
- Checking the Explorer count
- Checking the MailItem.EntryID
- MailItem.ConversationID
- MailItem.StoreID
- Retrieving the MailItem based on its ID and then performing the actions only for a locally saved file
However, my logic is being executed for other selected emails in the inbox, drafts, etc., not just for locally saved files.
Below is the code snippet I have tried:
public bool IsLocalFile(Outlook.MailItem mailItem)
{
if (string.IsNullOrEmpty(mailItem.EntryID) && string.IsNullOrEmpty(mailItem.StoreID))
{
return true;
}
return false;
}
public string GetLocalFilePath(Outlook.MailItem mailItem)
{
Outlook.PropertyAccessor propertyAccessor = mailItem.PropertyAccessor;
try
{
return propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7D01001E") as string;
}
catch (System.Exception ex)
{
return null;
}
}
public bool IsInFolder(Outlook.MailItem mailItem)
{
Outlook.MAPIFolder parentFolder = null;
try
{
parentFolder = mailItem.Parent as Outlook.MAPIFolder;
return parentFolder == null;
}
catch
{
}
return false;
}
public bool IsSaved(Outlook.MailItem mailItem)
{
Outlook.MAPIFolder parentFolder = mailItem.Parent as Outlook.MAPIFolder;
if (parentFolder!=null)
{
string folderPath = parentFolder.FolderPath;
if (folderPath=="C:\EmlFolder"||folderPath=="C:\Attachments")
{
return true;
}
}
string messageContent = mailItem.Body;
if (messageContent.Contains("Content-Type: multipart/related")||mailItem.BodyFormat==Outlook.OlBodyFormat.olFormatHTML)
{
return true;
}
if (mailItem.InternetCodepage==0)
{
return true;
}
return false;
}
public string GetLocalFilePath2(Outlook.MailItem mailItem)
{
if (!string.IsNullOrEmpty(mailItem.EntryID)&&string.IsNullOrEmpty(mailItem.StoreID))
{
Outlook.NameSpace outlookNamespace = mailItem.Session.Application.GetNamespace("MAPI");
Outlook.MailItem copiedMail = outlookNamespace.GetItemFromID(mailItem.EntryID);
if (copiedMail!=null&&!string.IsNullOrEmpty(copiedMail.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x370E001F")))
{
return copiedMail.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x370E001F") as string;
}
}
return null;
}
Then I check all above in a conditional:
if (mailItem.Session.Application.Explorers.Count == 0 ||
(string.IsNullOrWhiteSpace(mailItem.ConversationID) && !mailItem.IsDraft()) ||
IsLocalFile(mailItem) ||
!string.IsNullOrWhiteSpace(GetLocalFilePath(mailItem)) ||
!IsInFolder(mailItem) ||
IsSave(mailItem) ||
!string.IsNullOrWhiteSpace(GetLocalFilePath2(mailItem)))
{
// do stuff only in case it is a saved mail in local disk
}
Can anyone provide a reliable method to detect if a MailItem is a locally saved file opened in Outlook? I will highty appreciate it. Thanks in advance.