如何在NativeWindow中修复Excel VSTO项目中的ThreadAbortException?

时间:2015-08-23 06:31:17

标签: c# vb.net excel winforms vsto

在针对Office 2007和2010的VSTO项目中,我在ThisAddIn_Shutdown完成后收到ThreadAbortException。我相信这是由我实现的NativeWindow引起的,我在Shutdown中清理它。我正在使用NativeWindow,以便我的VSTO插件可以有HotKeys,我可以检测到哪些键被按下了。

有一个similar question here but I am not using it for a form so I cannot use this solution.

在此thread the problem is better explained.

  

您必须在关闭之前在主Excel窗口中释放子类。原因是加载程序响应主Excel窗口关闭而调用shutdown。因此,如果您在Excel主窗口关闭之前没有调用ReleaseHandle,WM_CLOSE将首先被分派到NativeWindow的托管WndProc。这会将托管代码放在加载器关闭代码下面的堆栈上。因此,加载程序调用shutdown并卸载AppDomain,但随后堆栈继续展开并遇到托管代码。由于AppDomain已被卸载,因此抛出AppDomainUnloadedException,但由于没有可用的处理程序,Excel崩溃。

但我再一次无法使用该解决方案,因为我没有将它用于表单。

据我所知,解决方案是在Excel关闭之前清理NativeWindow的东西。

我该怎么做?

我发现/想到的唯一一件事就是发送WM_CLOSE消息的of the solution to this Word issue.行。我可以取消应用程序退出清理我的本机窗口并自己关闭Excel。

但是我不确定Excel(2007/2010)是否会在关闭时提供一些知道的信息,以便及早取消。

1 个答案:

答案 0 :(得分:0)

试试这个:

public partial class ThisAddIn
{
    public MyNativeWindow MyNativeExcelWindow { get; private set; }

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        var excelHwnd_IntPtr = new IntPtr(Globals.ThisAddIn.Application.Hwnd);
        MyNativeExcelWindow = new MyNativeWindow();
        MyNativeExcelWindow.AssignHandle(excelHwnd_IntPtr);
        ...
    } 
    ...
}

public class MyNativeWindow : NativeWindow
{
    private const int WM_CLOSE = 16;

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_CLOSE) 
        {
            // Release handle for this native window before closing app...
            ReleaseHandle();

            // Then go on closing...
            PostMessage(m.HWnd, Convert.ToUInt32(m.Msg), m.WParam.ToInt32(), m.LParam.ToInt32());
        }
        else
        {
            // HERE YOU CAN PROCESS OTHER MESSAGES...

            base.WndProc(ref m);
        }
    }
}