From 486ec81425ecd262ddd05cedf6a1fcecbf75e070 Mon Sep 17 00:00:00 2001 From: Takashi Hashida Date: Thu, 12 Sep 2024 10:52:58 +0900 Subject: [PATCH] Do not use MailItem.EntryId and generate original mail id MailItem.EntryId is generated when a mail is saved. So We should use MailItem.Save. However, MailItem.Save may fail and do unexpected behavior when a mail item is an inline reply mail. So we generate an original id for a mail without using MailItem.Save. --- ThisAddIn.cs | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/ThisAddIn.cs b/ThisAddIn.cs index edb6129..e05a90c 100644 --- a/ThisAddIn.cs +++ b/ThisAddIn.cs @@ -51,10 +51,9 @@ private void ThisAddIn_NewExplorer(Outlook.Explorer explorer) private void SaveOriginalRecipients(object response, ref bool cancel) { Outlook.MailItem mailItem = response as Outlook.MailItem; - // EntryID is created when saving. - mailItem.Save(); - var entryID = mailItem.EntryID; - if (string.IsNullOrEmpty(entryID)) + + var mailID = GenerateMailID(mailItem); + if (string.IsNullOrEmpty(mailID)) { return; } @@ -63,7 +62,7 @@ private void SaveOriginalRecipients(object response, ref bool cancel) { originalRecipients.Add(new RecipientInfo(recp)); } - EntryIdToOriginalRecipientsDictionary[entryID] = originalRecipients; + EntryIdToOriginalRecipientsDictionary[mailID] = originalRecipients; } private void ThisAddIn_Shutdown(object sender, System.EventArgs e) @@ -184,8 +183,8 @@ private bool DoCheck(Outlook.MailItem mail) } config.Merge(Loader.LoadFromDir(StandardPath.GetDefaultConfigDir())); config.Merge(Loader.LoadFromDir(StandardPath.GetUserDir())); - - List originalRecipients = GetOriginalRecipientsFromDictionary(mail.EntryID); + var mailID = GenerateMailID(mail); + List originalRecipients = GetOriginalRecipientsFromDictionary(mailID); MainDialog mainDialog = new MainDialog(config, mail, originalRecipients); if (mainDialog.SkipConfirm()) @@ -198,35 +197,56 @@ private bool DoCheck(Outlook.MailItem mail) { if (!config.CountEnabled) { - RemoveRecipientsFromDictionary(mail.EntryID); + RemoveRecipientsFromDictionary(mailID); return true; } if (new CountDialog(config).ShowDialog() == true) { - RemoveRecipientsFromDictionary(mail.EntryID); + RemoveRecipientsFromDictionary(mailID); return true; } } return false; } - private List GetOriginalRecipientsFromDictionary(string entryID) + private List GetOriginalRecipientsFromDictionary(string mailID) { - if (string.IsNullOrEmpty(entryID)) + if (string.IsNullOrEmpty(mailID)) { return null; } - return EntryIdToOriginalRecipientsDictionary.ContainsKey(entryID) ? EntryIdToOriginalRecipientsDictionary[entryID] : null; + return EntryIdToOriginalRecipientsDictionary.ContainsKey(mailID) ? EntryIdToOriginalRecipientsDictionary[mailID] : null; } - private void RemoveRecipientsFromDictionary(string entryID) + private void RemoveRecipientsFromDictionary(string mailID) { - if (string.IsNullOrEmpty(entryID)) + if (string.IsNullOrEmpty(mailID)) { return; } - EntryIdToOriginalRecipientsDictionary.Remove(entryID); + EntryIdToOriginalRecipientsDictionary.Remove(mailID); + } + + private string GenerateMailID(Outlook.MailItem mailItem) + { + if(mailItem == null) + { + return null; + } + // Create an uniq id for this mail(response). mailItem.EntryID can use as uniq id, but + // mailItem.EntryID is created when saving, but this mail(response) is not saved yet. + // We can generate the entry id by executing mailItem.Save(), but mailItem.Save() + // may do unexpected behavior when a mail item is an inline reply, so we can't use it. + // + // https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.save + // > If a mail item is an inline reply, calling Save on that mail item may fail and result in unexpected behavior. + var index = mailItem.ConversationIndex ?? ""; + var topic = mailItem.ConversationTopic ?? ""; + + // For mails that have no index and no topic, we give up to specify an uniq id, and mailId for them becomes "_". + // Among those mails, recipients of the last mail that passes this method is regarded as original recipients. + return $"{topic}_{index}"; } protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()