【发布时间】:2020-05-17 08:48:05
【问题描述】:
我想要实现的是还使用 Inspector 上的 AppProperty Change 事件正确处理日历上的拖放事件:
每当用户与界面交互时,我都会更新 currentAppointmentItem(Explorer.SelectionChange、NewInspector、CloseInspector 等) 每当用户与界面交互时,我都会更新 currentInspector(SelectionChange、NewInspector、CloseInspector) 更新意味着我尝试适当地设置/取消设置事件处理程序,并相应地设置/取消设置 Marshal.ReleaseComObject。最后将引用清空。
但是当用户只点击日历中的 AppointmentItem 时,不会创建 Inspector 窗口。因此我无法捕捉 AppPropertyChange 事件。所以我决定在选定的 AppointmentItem 上调用 GetInspector,以防它不为空。我尝试使用它来接收 AppProperty 事件的更改,以便我可以正确处理日历上的拖放事件
问题:从 Microsoft 文档中我了解到,每当您丢失对 currentAppointmentItem 的引用时,您还应该使用 Marshal.ReleaseComObject ,否则您可能会遇到其他问题。 现在我遇到了我无法捕捉到的异常:RaceOnRCWCleanup ...似乎我试图释放一个仍在使用的 COM 对象(可能由 Outlook 使用)。我怎样才能避免这种情况? Marshal.ReleaseComObject(currentAppointmentItem) 是否正确
我在 Outlook.Explorer 上注册了 SelectionChange 事件。在那里我尝试注册 currentAppointment:
[...]
log.Info("Selection_Change");
if (currentExplorer == null)
{
return;
}
try
{
log.Info("Selection_Change: " + currentExplorer.Caption);
Outlook.MAPIFolder selectedFolder = currentExplorer.CurrentFolder;
if (currentExplorer.Selection.Count > 0)
{
Object selObject = currentExplorer.Selection[1];
if (selObject is Outlook.AppointmentItem)
{
currentAppointmentItem = (Outlook.AppointmentItem)selObject;
Inspectors_NewInspector(currentAppointmentItem.GetInspector);
}
[...]
请注意:INspectors_NewInspector 也会在 Inspectors 集合中调用。
NewInspector 的代码是这样的
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
try
{
log.Info("Inspectors_NewInspector");
// This function (apparently) gets kicked off whenever a user opens a new or existing item
// in Outlook (Calendar appointment, Email, etc).
// We can intercept it, modify it's properties, before letting our Ribbon know about its existance.
//
if (Inspector != null)
{
log.Info("Inspectors_NewInspector: " + Inspector.Caption);
unregisterCurrentInspector();
currentInspector = Inspector;
object item = Inspector.CurrentItem;
if (item == null)
return;
if (!(item is Outlook.AppointmentItem))
return;
unregisterCurrentAppointmentItem();
currentAppointmentItem = (Outlook.AppointmentItem)item;
currentAppointmentItem.PropertyChange += AppPropertyChanged; // Handle situations where the
// user tries to convert an appointment w/ an agreedo protocol to a recurring appointment.
// This needs to be avoided .
currentAppointmentItem.CustomPropertyChange += AppPropertyChanged;
}
((Microsoft.Office.Interop.Outlook.InspectorEvents_10_Event)Inspector).Close += Inspector_Close;
} catch (Exception ex)
{
log.Error(ex.Message);
}
}
unregisterCurrentApppointmentItem:
private void unregisterCurrentAppointmentItem()
{
try
{
log.Info("unregisterCurrentAppointmentItem");
if (currentAppointmentItem != null)
{
currentAppointmentItem.PropertyChange -= AppPropertyChanged; // Handle situations where the
currentAppointmentItem.CustomPropertyChange -= AppPropertyChanged;
Marshal.ReleaseComObject(currentAppointmentItem);
currentAppointmentItem = null;
}
} catch (Exception ex)
{
log.Error(ex.Message);
}
}
unregisterCurrentInspector:
private void unregisterCurrentInspector()
{
log.Info("unregisterCurrentInspector");
if (currentInspector != null)
{
((Microsoft.Office.Interop.Outlook.InspectorEvents_10_Event)currentInspector).Close -= Inspector_Close;
Marshal.ReleaseComObject(currentInspector);
currentInspector = null;
}
}
对此有何建议?
我已经尝试/考虑过的内容:
【问题讨论】:
标签: outlook vsto outlook-addin