Excel 2013崩溃

我试图将Excel 2013embedded到WPF应用程序中。 问题是,当我在以下代码中调用SetWindowLongPtr时,Excel 2013立即崩溃。 我挖了它,发现如果我注释掉WS.CHILD风格,它工作正常,但Excel表变成只读,这不是我想要的。 相同的代码与Excel 2010工作正常。

 Excel.Application _excelApp; IntPtr _wrappedApplicationHandle; Int64 lngStyle; Int64 lExStyle; private void Button_Click_1(object sender, RoutedEventArgs e) { _excelApp = new Excel.Application() { Visible = true, DisplayFormulaBar = true, }; _wrappedApplicationHandle = new IntPtr( _excelApp.Hwnd); lngStyle = GetWindowLongPtr(_wrappedApplicationHandle, (int)GWL.STYLE).ToInt64(); lngStyle &= ~(int)WS.CAPTION; lngStyle &= ~(int)WS.SIZEBOX; lngStyle |= (int)WS.MAXIMIZE; lngStyle |= (int)WS.CHILD; //<< crashes with this line lngStyle |= (int)WS.CLIPSIBLINGS; lngStyle |= (int)WS.CLIPCHILDREN; SetWindowLongPtr(new HandleRef(_excelApp, _wrappedApplicationHandle), (int)GWL.STYLE, new IntPtr(lngStyle)); ... } 

编辑

我正在挖掘更多的信息。 我尝试在try / catch块中包装上面的代码,看看会发生什么。 它永远不会到达catch块。 Excel 2013崩溃与臭名昭着的“应用程序已停止工作。发送报告给MS”错误。 我已经打开了Visual Studio中的所有Win32 / COM / C ++exception(通过debugging菜单> exception对话框),但这也没有帮助。 在错误对话框中有一个debuggingbutton。 如果我点击并打开一个debugging器,我看到的错误消息是“0xC0000005:访问冲突读取位置0x0000000000000000”。

我还发现,在上面的代码中注释掉WS.CHILD行并不严格地使工作表只读。 它只是阻止到达工作表的常见键盘/鼠标input。 但是键盘的上下文菜单键等键仍然到达,上下文菜单显示(鼠标右键不能正常工作)。 同样,我可以通过鼠标与Officefunction区进行交互。 看起来好像只有工作表区域(白色背景的网格)没有接收键盘/鼠标input。

编辑2

我刚刚回想起(与Hans Passant在下面的post中解释的),VS2010在创buildExcel VSTO工作簿项目时主持了一个Excel实例。 虽然我没有VS2013(Full)和我无法确认,但我怀疑VS2013会做Excel 2013 VSTO Workbook项目。 考虑到VS2010及以上版本都是WPF应用程序本身,那么如何适合WPF呢?

编辑3

@acelentbuild议的私有接口理论(见下面的评论)似乎是正确的。 我窥探到VS2010托pipe的Excel实例,发现有一个新的窗口,classname = EXCELI ,当我们正常打开Excel(窗口的正常层次结构是XLMAIN(应用程序)> XLDESK(工作区)> EXCEL7(工作簿) )。 此外,该工作簿不再以ActiveX对象的forms提供,在Office Web Components库可用(上次随Office 2003提供)的情况下,该对象曾经是后面的例子。 所以总而言之,我们似乎处于一个死胡同的地步,除非有人在接下来的几个小时内提出实际的工作方法,否则我会build议@汉斯给我的客户的答案。

你需要放弃这个,你不能使它可靠地工作。

WS_CHILD不能通过devise工作,Windows有父窗口和子窗口属于同一进程的硬性要求。 它们在彼此之间传递消息,当试图取消引用属于父进程的指针时,subprocess会崩溃。

Windows确实对SetParent()有一些appcompat支持,因为这通常是在Windows 3.x程序中完成的。 在Windows版本中,具有独立地址空间的进程的概念完全不存在,所以当时不是问题。 20年后这个问题仍然可以正常运行的几率与Windows 3.x应用程序的运行程度成正比。 它适用于控制台窗口或简单的应用程序,如记事本。 Office 2013应用程序大大超出了简单和3.x. 对input有困难肯定是这个标志。 你可以修改AttachThreadInput()来尝试解决这个问题,但是你可能会直接面对下一个问题,包括在debugging时引起死锁的恶习。

embeddedOffice应用程序曾经是Office强烈支持的function,Microsoft有意将其devise为可embedded。 基础技术被称为OLE链接和embedded。 然而,这项技术被强烈弃用。 它的支持被有意地排除在.NET Framework之外。 Office 2003是仍然支持它的最后一个版本。 麻烦从2007年开始,到2010年完全被废弃了。它不会回来。

前面的道路是完全相反的。 不要embeddedOffice应用程序,让Office应用程序embedded您的应用程序。 强烈支持为Office程序编写加载项。