VSTO:事件处理程序在重启后无法触发
VSTO: Event Handler failing to fire after a reboot
我在适用于 Outlook 的 C# VSTO 插件中遇到问题。
有一个在启动时注册的事件处理程序,当一个项目被选中时,它会更新主资源管理器 Window 功能区上的一个按钮。最初部署时(通过 Clickonce)插件工作完美。每次更改选择都会更新按钮。
下面是注册事件处理器的代码:
Outlook.ExplorerEvents_10_SelectionChangeEventHandler selectionChangeEventHandler;
private void RegisterEvents(Outlook.Explorer Explorer)
{
try
{
log.Debug("Registering Events");
Application.Explorers.NewExplorer += Explorers_NewExplorer;
selectionChangeEventHandler = new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(ThisAddIn_SelectionChange);
Explorer.SelectionChange -= selectionChangeEventHandler;
Explorer.SelectionChange += selectionChangeEventHandler;
this.Application.OptionsPagesAdd -= Application_OptionsPagesAdd;
this.Application.OptionsPagesAdd += Application_OptionsPagesAdd;
Application.ItemSend -= Application_ItemSend;
Application.ItemSend += Application_ItemSend;
log.Debug("Events Registration Succeeded");
}
catch (Exception ex)
{
log.Debug("Event Registration Failed");
log.Error(ex.Message);
log.Error(ex.StackTrace);
}
}
private void Explorers_NewExplorer(Outlook.Explorer Explorer)
{
RegisterEvents(Explorer);
}
像这样调用注册方法
RegisterEvents(Application.ActiveExplorer());
但是在重新启动后,事件处理程序会触发两次,然后再也不会触发。
为了尝试追踪问题,如果在 app.config 中设置了字符串(如下所示),我添加了一行以启动调试器
if (String.Equals(ConfigurationManager.AppSettings.Get("attachDebugger"), "true", StringComparison.OrdinalIgnoreCase))
Debugger.Launch();
重新启动后,我可以启动 Outlook 并看到插件无法更新选择。然后关闭 Outlook,切换配置中的 attachDebugger 标志,按钮立即开始工作。
插件中的所有其他功能都可以正常工作,因此插件不会突然停止运行。
我不知道下一步该做什么。如果有人对为什么事件处理程序在重启前后应该 运行 有不同的看法(偶然卸载并重新安装插件会导致它在该会话中再次工作),我将非常感激。我也欢迎任何人提出建议,当问题无法在调试器下显示时,他们可以建议调试应用程序的方法。
您需要一个全局 (class) 变量来存储指向 Explorer 对象的指针。否则它会被垃圾收集器释放。如果不这样做,它只会在发布之前触发事件。
我在适用于 Outlook 的 C# VSTO 插件中遇到问题。
有一个在启动时注册的事件处理程序,当一个项目被选中时,它会更新主资源管理器 Window 功能区上的一个按钮。最初部署时(通过 Clickonce)插件工作完美。每次更改选择都会更新按钮。
下面是注册事件处理器的代码:
Outlook.ExplorerEvents_10_SelectionChangeEventHandler selectionChangeEventHandler;
private void RegisterEvents(Outlook.Explorer Explorer)
{
try
{
log.Debug("Registering Events");
Application.Explorers.NewExplorer += Explorers_NewExplorer;
selectionChangeEventHandler = new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(ThisAddIn_SelectionChange);
Explorer.SelectionChange -= selectionChangeEventHandler;
Explorer.SelectionChange += selectionChangeEventHandler;
this.Application.OptionsPagesAdd -= Application_OptionsPagesAdd;
this.Application.OptionsPagesAdd += Application_OptionsPagesAdd;
Application.ItemSend -= Application_ItemSend;
Application.ItemSend += Application_ItemSend;
log.Debug("Events Registration Succeeded");
}
catch (Exception ex)
{
log.Debug("Event Registration Failed");
log.Error(ex.Message);
log.Error(ex.StackTrace);
}
}
private void Explorers_NewExplorer(Outlook.Explorer Explorer)
{
RegisterEvents(Explorer);
}
像这样调用注册方法
RegisterEvents(Application.ActiveExplorer());
但是在重新启动后,事件处理程序会触发两次,然后再也不会触发。
为了尝试追踪问题,如果在 app.config 中设置了字符串(如下所示),我添加了一行以启动调试器
if (String.Equals(ConfigurationManager.AppSettings.Get("attachDebugger"), "true", StringComparison.OrdinalIgnoreCase))
Debugger.Launch();
重新启动后,我可以启动 Outlook 并看到插件无法更新选择。然后关闭 Outlook,切换配置中的 attachDebugger 标志,按钮立即开始工作。
插件中的所有其他功能都可以正常工作,因此插件不会突然停止运行。
我不知道下一步该做什么。如果有人对为什么事件处理程序在重启前后应该 运行 有不同的看法(偶然卸载并重新安装插件会导致它在该会话中再次工作),我将非常感激。我也欢迎任何人提出建议,当问题无法在调试器下显示时,他们可以建议调试应用程序的方法。
您需要一个全局 (class) 变量来存储指向 Explorer 对象的指针。否则它会被垃圾收集器释放。如果不这样做,它只会在发布之前触发事件。