Excel VSTO中的Form.Show(IWin32Window)方法在应用程序closures时导致ThreadAbortException

我有一个Excel插件,我有一个窗体,我想成为excel窗口的前面。 为此,我使用NativeWindow作为excelfunction区菜单button,如下所示:

 public partial class MyRibbonMenu { public List<Form> Forms = new List<Form>(); private void button1_Click(object sender, RibbonControlEventArgs e) { // initialize form Form frm = new Form(); frm.Text = "Test Form"; Forms.Add(frm); // create the native window handle NativeWindow nw = new NativeWindow(); IntPtr iptr = new IntPtr(Globals.ThisAddIn.Application.Hwnd); nw.AssignHandle(iptr); // when close the form release the handle frm.FormClosed += (sender2, e2) => { Forms.Remove(frm); nw.ReleaseHandle(); }; // show with owner frm.Show(nw); } } 

如果我在退出excel之前closures表格,那么一切正常,这样做很好。 但是,如果用户不想closures打开的窗体而退出Excel,则会发生ThreadAbortExceptionexception:

System.Windows.Forms.dll中发生未处理的types“System.Threading.ThreadAbortException”exception

其他信息:线程正在中止。

为了解决这个问题,我尝试了下面的代码,但没有工作:

 private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { var frms = Globals.Ribbons.MyRibbonMenu.Forms.ToArray(); foreach (var frm in frms) { frm.Close(); } } 

我可以在哪里犯错?

我使用IWin32Window接口而不是NativeWindow来解决问题:

 public class Win32Window : System.Windows.Forms.IWin32Window { public Win32Window(int windowHandle) { _windowHandle = new IntPtr(windowHandle); } IntPtr _windowHandle; public IntPtr Handle { get { return _windowHandle; } } } 

在这之后,我改变了下面的表单初始化代码:

 private void button1_Click(object sender, RibbonControlEventArgs e) { // initialize form var frm = new Form(); frm.FormBorderStyle = FormBorderStyle.FixedSingle; frm.MinimizeBox = false; frm.MaximizeBox = false; frm.Text = "Test Form"; frm.StartPosition = FormStartPosition.CenterScreen; Forms.Add(frm); // create the native window handle var nw = new Win32Window(Globals.ThisAddIn.Application.Hwnd); // show with owner frm.Show(nw); } 

编辑:我在这里添加我的答案b \ c用户的答案是一个解决方法,而不是一个问题可能是一个解释:我build议检查解决scheme微软推出和修改您的需求。

看到我的答案在这里: https : //stackoverflow.com/a/38157476/取决于你试图听你在什么窗口也许糟an了一个非托pipe窗口监听器,不幸的是NativeWindow.ReleaseHandle不知道如何恢复子类化窗口链,而是取而代之的WindowsWndproc您更改User32!DefWindowProc [这]会导致应用程序崩溃或挂起。