使用 VSTO 和 C# 仅获取 Outlook 电子邮件中的最新回复文本
Only get the latest reply text in an Outlook Email using VSTO and C#
我已经浏览了很多链接,但其中 none 似乎有效。我的问题是,在使用 C# 和 VSTO 编写的 Outlook 加载项中,我希望捕获最新回复电子邮件的文本到一个线程。
问题是 MailItem 对象的所有属性(例如 Body、HTMLBody 等)都给出了电子邮件的完整文本,包括过去的回复。我希望以某种方式只获取最新的文本。考虑到电子邮件中的多种语言,我需要能够做到这一点。
这是我试过的
- 在 MailEditor 上使用书签 - exchange 和 Outlook 似乎不再有 _MailOriginal 书签
- 不知何故试图阻止 MIME 属性 - 我不太了解选择哪些属性以及如何使用它们来解析最近的文本。
Outlook 对象模型没有为此提供任何东西。您需要自行解析消息正文字符串。
此外,您可以遍历对话中的所有项目,并在 latest/recent 项目中检测每个项目。通过删除旧项目,您可以获得最新的。以下示例显示如何在对话中获取和显示邮件项目。
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);
}
}
}
在示例代码示例中,我们获取一个选中的MailItem
对象,然后通过Store
属性确定MailItem
对象的存储=14=] 对象。 DemoConversation 然后检查 IsConversationEnabled
属性 是否为真;如果为真,则代码示例使用 GetConversation
方法获取 Conversation
对象。如果 Conversation
对象不是空引用,该示例将使用 GetTable
方法获取包含对话中每个项目的关联 Table
对象。然后该示例枚举 Table
中的每个项目,并对每个项目调用 EnumerateConversation
以访问每个项目的子节点。 EnumerateConversation
获取一个 Conversation
对象并使用 GetChildren(Object)
方法获取子节点。 EnumerateConversation
被递归调用,直到没有更多的子节点。然后向用户显示每个对话项目。
即使在理论上你也不能这样做:想象一个用户在消息的顶部打字(例如 "see below"),然后 inserting/deleting 下面的消息正文中的各个部分(我都是这样做的)时间)。如果字体颜色不同,你很幸运。
您可以尝试将原始邮件与新邮件进行比较并找出差异,但这需要访问原始邮件。您可以查看 PR_IN_REPLY_TO_ID
MAPI 属性(DASL 名称 http://schemas.microsoft.com/mapi/proptag/0x1042001F
)并尝试在“收件箱”或“已发送邮件”文件夹中找到原始邮件。请注意,在后一种情况(已发送邮件文件夹)中,属性 可能在缓存邮件中不可用,您需要搜索该文件夹的在线版本(在 OOM 中不能这样做,您需要扩展C++ 中的 MAPI 或 Delphi 或任何语言的 Redemption)。
我已经浏览了很多链接,但其中 none 似乎有效。我的问题是,在使用 C# 和 VSTO 编写的 Outlook 加载项中,我希望捕获最新回复电子邮件的文本到一个线程。
问题是 MailItem 对象的所有属性(例如 Body、HTMLBody 等)都给出了电子邮件的完整文本,包括过去的回复。我希望以某种方式只获取最新的文本。考虑到电子邮件中的多种语言,我需要能够做到这一点。
这是我试过的
- 在 MailEditor 上使用书签 - exchange 和 Outlook 似乎不再有 _MailOriginal 书签
- 不知何故试图阻止 MIME 属性 - 我不太了解选择哪些属性以及如何使用它们来解析最近的文本。
Outlook 对象模型没有为此提供任何东西。您需要自行解析消息正文字符串。
此外,您可以遍历对话中的所有项目,并在 latest/recent 项目中检测每个项目。通过删除旧项目,您可以获得最新的。以下示例显示如何在对话中获取和显示邮件项目。
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);
}
}
}
在示例代码示例中,我们获取一个选中的MailItem
对象,然后通过Store
属性确定MailItem
对象的存储=14=] 对象。 DemoConversation 然后检查 IsConversationEnabled
属性 是否为真;如果为真,则代码示例使用 GetConversation
方法获取 Conversation
对象。如果 Conversation
对象不是空引用,该示例将使用 GetTable
方法获取包含对话中每个项目的关联 Table
对象。然后该示例枚举 Table
中的每个项目,并对每个项目调用 EnumerateConversation
以访问每个项目的子节点。 EnumerateConversation
获取一个 Conversation
对象并使用 GetChildren(Object)
方法获取子节点。 EnumerateConversation
被递归调用,直到没有更多的子节点。然后向用户显示每个对话项目。
即使在理论上你也不能这样做:想象一个用户在消息的顶部打字(例如 "see below"),然后 inserting/deleting 下面的消息正文中的各个部分(我都是这样做的)时间)。如果字体颜色不同,你很幸运。
您可以尝试将原始邮件与新邮件进行比较并找出差异,但这需要访问原始邮件。您可以查看 PR_IN_REPLY_TO_ID
MAPI 属性(DASL 名称 http://schemas.microsoft.com/mapi/proptag/0x1042001F
)并尝试在“收件箱”或“已发送邮件”文件夹中找到原始邮件。请注意,在后一种情况(已发送邮件文件夹)中,属性 可能在缓存邮件中不可用,您需要搜索该文件夹的在线版本(在 OOM 中不能这样做,您需要扩展C++ 中的 MAPI 或 Delphi 或任何语言的 Redemption)。