Microsoft Outlook アドイン (Visual Studio 2012、C#、COM アドイン、VSTO なし、Outlook 2010/2013/2016) を作成しています。このアドインでは、ユーザーがさまざまなフィールドを作成して読み取ることができなければなりません。メッセージが Microsoft Exchange を出入りするときの MIME ヘッダー (名前空間 PS_INTERNET_HEADERS のプロパティ)。
ユーザーがメッセージを転送するときに、元のメッセージから転送されたメッセージにプロパティをコピーしたいと考えています。これを行うには、イベント Application.ItemLoad と MailItem.Forward をリッスンします。後者のイベント ハンドラーでコピーが行われます。
これは、開発マシンの Outlook 2013 バージョン 15.0.4771.1000 では正常に機能しますが、仮想マシンで実行されている Outlook 2013 バージョン 15.0.4771.1000 では機能しません。Outlook 2010 を使用する他の仮想マシンでも機能しません。
問題は、転送されたメッセージの Inspectors.NewInspector のイベント ハンドラーでプロパティ値を読み取ると、予期せず空の値が返されることです。しかし、件名などを変更し、転送されたメッセージの下書きを保存して再度開くと、プロパティ値は期待どおりになります。したがって、プロパティは何らかの形で変更されますが、NewInspector のイベント ハンドラーで最初に読み取ったときに反映されません。私は何を間違っていますか?
以下は、問題を示すサンプル コードです。問題を証明するために必要と思われるクリーンアップ コードのみを含めました。
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ForwardTest
{
public class Application
{
private readonly Outlook.Application application;
private readonly HashSet<MailItem> loadedMailItems;
public Application(Outlook.Application application)
{
this.application = application;
loadedMailItems = new HashSet<MailItem>();
application.ItemLoad += ItemLoad;
application.Inspectors.NewInspector += NewInspector;
}
private void ItemLoad(object item)
{
loadedMailItems.Add(new MailItem((Outlook.MailItem)item));
}
private void NewInspector(Outlook.Inspector inspector)
{
var mailItem = (Outlook.MailItem)inspector.CurrentItem;
// Next line unexpectedly shows empty values for some Outlook versions.
System.Windows.Forms.MessageBox.Show(Properties.Get(mailItem), Properties.FooName);
}
}
public class MailItem
{
private readonly Outlook.MailItem mailItem;
public MailItem(Outlook.MailItem mailItem)
{
this.mailItem = mailItem;
((Outlook.ItemEvents_10_Event)mailItem).Forward += Forward;
}
private void Forward(object forward, ref bool cancel)
{
var value = Properties.Get(mailItem);
Properties.Set((Outlook.MailItem)forward, "FW: " + value);
Marshal.ReleaseComObject(forward);
}
}
public static class Properties
{
public const string FooName = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/MMHS-Foo";
public static string Get(Outlook.MailItem mailItem)
{
var propertyAccessor = mailItem.PropertyAccessor;
var values = (object[])propertyAccessor.GetProperties(new[] { FooName });
var value = values[0] as string ?? string.Empty;
Marshal.ReleaseComObject(propertyAccessor);
return value;
}
public static void Set(Outlook.MailItem mailItem, string value)
{
var propertyAccessor = mailItem.PropertyAccessor;
propertyAccessor.SetProperty(FooName, value);
Marshal.ReleaseComObject(propertyAccessor);
}
}
}