本地窗口:关闭时释放句柄

7

我目前正在开发一个适用于 Microsoft Outlook 的 C# .NET 插件。 该插件的目标是捕获 Outlook 即时搜索的搜索输入,并在自定义面板中显示我的搜索结果。

它运行得非常好,通过使用本机窗口对 Outlook 窗口进行子类化,我可以获取搜索字符串,并将其传递到我的面板中。

问题在于,当您关闭插件(通过“文件->选项->加载项->COM 加载项”,但不是使用面板中的 X)时,插件会立即终止,我无法在此之前调用 searchboxWindow.ReleaseHandle() 来恢复我的 WndProc 链。Outlook 会崩溃,没有任何可见的错误。

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    switch ((uint)m.Msg)
    {
        case WindowMessages.WM_DESTROY:
        case WindowMessages.WM_QUIT:
        case WindowMessages.WM_NCDESTROY:
            this.ReleaseHandle();
            return;

        case WindowMessages.WM_KEYUP:
        case WindowMessages.WM_LBUTTONDOWN:
        case WindowMessages.WM_RBUTTONDOWN:
            OnKeyUp();
            break;

        case WindowMessages.WM_EXITSIZEMOVE:
            OnResize();
            break;
    }
}

我已经尝试监听一些窗口消息,这些消息应该在插件关闭时调用,但是当我以正常方式关闭Outlook时,这些消息只出现一次。

此外,主要的Add-In源文件中的事件,如AppDomain.CurrentDomain.ProcessExitthis.Shutdown((Outlook.ApplicationEvents_10_Event)this.Application).Quit都没有被调用。

有哪些事件可以监听,能够可靠地在插件终止时触发?如果没有,我有哪些解决问题的替代方案?


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mr. B
我实现了IDisposable接口,并在其中调用ReleaseHandle()方法,但是没有任何效果?这是你的意思吗? - Florian Schöffl
3
使用插件的 Shutdown 事件来取消窗口的子类化。自动生成的 ThisAddIn_Shutdown() 事件处理程序语言有些可怕,但在这种特定情况下仍会被触发。 - Hans Passant
从Outlook 2010开始,Outlook在关闭时不再调用ThisAddin_Shutdown方法。来源 - 您确定在这种情况下会被调用吗?我现在无法检查。 - Florian Schöffl
1
这可能是你需要实现 finalizer 的罕见情况之一。请查看此文章 https://limbioliong.wordpress.com/2011/07/03/invoking-finalizers-of-net-based-com-objects-in-an-unmanaged-app-part-1/。 - Scott Chamberlain
3个回答

1

已解决:感谢Hans Passant

看起来当插件通过COM插件对话框手动断开连接时,ThisAddIn_Shutdown事件确实会被触发。


0

我认为在托管代码中你无法做太多事情。非托管代码将会很好地工作;COM系统会通过调用你的DllCanUnload实现礼貌地询问你的dll是否可以卸载。


所以基本上除非我用C++或类似的语言重写我的项目,否则我什么也做不了? - Florian Schöffl

0
请确保在您的插件注册表中添加一个DWORD RequireShutdownNotification=1,否则ThisAddIn_Shutdown()将不会被调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接