问题
I have gone through many links already but none of them seems to be working. My problem is that in an Outlook Add-In written using C# and VSTO, I am looking to capture the text of the latest Reply email to a thread.
The problem is that all the properties on a MailItem object such as Body, HTMLBody etc give the entire text of the email including past replies. I am looking to somehow only get the most recent text. And I need to be able to do this considering multiple languages in an email.
Here is what i have tried
- Using Bookmarks on the MailEditor - There seems to be no more _MailOriginal bookmark with exchange and Outlook
- Somehow trying to get hold off MIME properties - I don't know enough on which properties to pick and how to use them to parse the recent text.
回答1:
You cannot do that even in theory: imagine a user typing at the top of the message (e.g. "see below") and then inserting/deleting various pieces in the message body below (I do that all the time). You are lucky if the font color is different.
You can try to compare the original with the new and figure out the diff, but that requires access to the original message. You can look at the PR_IN_REPLY_TO_ID
MAPI property (DASL name http://schemas.microsoft.com/mapi/proptag/0x1042001F
) and try to find the original message either in the Inbox or the Sent Items folder. Note that in the latter case (Sent Items folder) the property might not be available on the cached message, you'd need to search the online version of the folder (cannot do that in OOM, you'd need Extended MAPI in C++ or Delphi or Redemption in any language).
回答2:
The Outlook object model doesn't provide anything for that. You need to parse the message body string on your own.
Also, you can iterate over all items in the conversation and detect each of them in the latest/recent item. By removing older items you can get the latest. The following example shows how to get and display mail items in a conversation.
void DemoConversation()
{
object selectedItem = Application.ActiveExplorer().Selection[1];
// For this example, you will work only with
//MailItem. Other item types such as
//MeetingItem and PostItem can participate
//in Conversation.
if (selectedItem is Outlook.MailItem)
{
// Cast selectedItem to MailItem.
Outlook.MailItem mailItem = selectedItem as Outlook.MailItem;
// Determine store of mailItem.
Outlook.Folder folder = mailItem.Parent as Outlook.Folder;
Outlook.Store store = folder.Store;
if (store.IsConversationEnabled == true)
{
// Obtain a Conversation object.
Outlook.Conversation conv = mailItem.GetConversation();
// Check for null Conversation.
if (conv != null)
{
// Obtain Table that contains rows
// for each item in Conversation.
Outlook.Table table = conv.GetTable();
Debug.WriteLine("Conversation Items Count: " + table.GetRowCount().ToString());
Debug.WriteLine("Conversation Items from Table:");
while (!table.EndOfTable)
{
Outlook.Row nextRow = table.GetNextRow();
Debug.WriteLine(nextRow["Subject"]
+ " Modified: "
+ nextRow["LastModificationTime"]);
}
Debug.WriteLine("Conversation Items from Root:");
// Obtain root items and enumerate Conversation.
Outlook.SimpleItems simpleItems = conv.GetRootItems();
foreach (object item in simpleItems)
{
// In this example, enumerate only MailItem type.
// Other types such as PostItem or MeetingItem
// can appear in Conversation.
if (item is Outlook.MailItem)
{
Outlook.MailItem mail = item as Outlook.MailItem;
Outlook.Folder inFolder = mail.Parent as Outlook.Folder;
string msg = mail.Subject
+ " in folder " + inFolder.Name;
Debug.WriteLine(msg);
}
// Call EnumerateConversation
// to access child nodes of root items.
EnumerateConversation(item, conv);
}
}
}
}
}
void EnumerateConversation(object item, Outlook.Conversation conversation)
{
Outlook.SimpleItems items = conversation.GetChildren(item);
if (items.Count > 0)
{
foreach (object myItem in items)
{
// In this example, enumerate only MailItem type.
// Other types such as PostItem or MeetingItem
// can appear in Conversation.
if (myItem is Outlook.MailItem)
{
Outlook.MailItem mailItem = myItem as Outlook.MailItem;
Outlook.Folder inFolder = mailItem.Parent as Outlook.Folder;
string msg = mailItem.Subject
+ " in folder " + inFolder.Name;
Debug.WriteLine(msg);
}
// Continue recursion.
EnumerateConversation(myItem, conversation);
}
}
}
In the sample code example, we get a selected MailItem
object and then determine the store of the MailItem
object by using the Store
property of the Folder
object. DemoConversation then checks whether the IsConversationEnabled
property is true; if it is true, the code example gets Conversation
object by using the GetConversation
method. If the Conversation
object is not a null reference, the example gets the associated Table
object that contains each item in the conversation by using the GetTable
method. The example then enumerates each item in the Table
and calls EnumerateConversation
on each item to access the child nodes of each item. EnumerateConversation
takes a Conversation
object and gets the child nodes by using the GetChildren(Object)
method. EnumerateConversation
is called recursively until there are no more child nodes. Each conversation item is then displayed to the user.
来源:https://stackoverflow.com/questions/61757154/only-get-the-latest-reply-text-in-an-outlook-email-using-vsto-and-c-sharp