В последних версиях Outlook, если вы отвечаете на электронное письмо, вы можете увидеть уведомление в разделе «Тема и адрес электронной почты» «Вы ответили на это сообщение…». Также обычно есть значок, показывающий, что ответ на это письмо отправлен. Как я могу получить список всех писем, на которые еще не ответили? Есть ли способ сделать это программно?
Я пробовал следующий подход, но он не фильтрует нужные элементы:
private static void GetUnrepliedEmails()
{
Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace outlookNamespace = outlookApp.GetNamespace("MAPI");
MAPIFolder inboxFolder = outlookNamespace.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
Items items = inboxFolder.Items;
foreach (dynamic item in items)
{
if (item is MailItem)
{
// Get the value of the PR_LAST_VERB_EXECUTION_TIME property
DateTime lastVerbExecutionTime = DateTime.MinValue;
foreach (ItemProperty prop in item.ItemProperties)
{
if (prop.Name == "http://schemas.microsoft.com/mapi/proptag/0x10820040")
{
lastVerbExecutionTime = (DateTime)prop.Value;
break;
}
}
// Check if the item has been replied to
if (lastVerbExecutionTime > DateTime.MinValue && item.ReceivedTime < lastVerbExecutionTime)
{
Console.WriteLine(item.Subject);
Console.WriteLine("---- You have replied to the message.");
}
else
{
Console.WriteLine(item.Subject);
Console.WriteLine("You have not replied to the message.");
}
}
}
}
Обновлено:
using Microsoft.Office.Interop.Outlook;
namespace TestOutlookCodes
{
class Program
{
static void Main(string[] args)
{
GetUnrepliedEmails();
}
private static void GetUnrepliedEmails()
{
Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace outlookNamespace = outlookApp.GetNamespace("MAPI");
MAPIFolder inboxFolder = outlookNamespace.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
// Use dynamic in case there are other than mailitems in the inbox
foreach (dynamic item in items)
{
if (item is MailItem)
{
// Check if email has been already replied here
bool hasBeenReplied = ...? // Items items = inboxFolder.Items.Restrict("@SQL=\"http://schemas.microsoft.com/mapi/proptag/0x10820040\" IS NULL");
Console.WriteLine(item.Subject);
}
}
}
}
}
Во-первых, свойство PR_LAST_VERB_EXECUTION_TIME
MAPI не будет присутствовать в коллекции MailItem.ItemProperties
: оно содержит только свойства OOM. Если вам нужно получить свойство MAPI, используйте MailItem.PropertyAccessor.GetProperty
Во-вторых, не перебирайте все элементы в папке, используйте Items.Find/FindNext
или Items.Restrict
со следующим запросом:
Items items = inboxFolder.Items.Restrict("@SQL=\"http://schemas.microsoft.com/mapi/proptag/0x10820040\" IS NULL");
Да, "IS NOT NULL" должно работать.
Вероятно, вам нужна функция, которая принимает MAPIFolder в качестве аргумента, проверяет эту папку, а затем рекурсивно вызывает себя для каждой дочерней папки (MAPIFolder.Folders).
Вы можете получить свойство PR_LAST_VERB_EXECUTION_TIME
, используя MailItem.PropertyAccessor.GetPropertty. Если свойство отсутствует, будет возбуждено исключение — вам нужно перехватить его и использовать как указание на то, что свойство не существует, и, следовательно, на сообщение не ответили. Но не перебирайте все элементы в папке, используйте Find/FindNext
или Restrict
.
Почти: имя свойства должно быть в формате DASL.
Я думаю, что у меня это сработало, даже без TRY/CATCH, но с использованием вашего предложения. Вы держите единственную в своем роде информацию об Outlook. Еще раз спасибо за помощь и за то, что делитесь своими знаниями!
да, этот код выглядит хорошо для меня. Делает ли он то, что вы от него ожидаете?