gpt4 book ai didi

c# - Excel 2013 崩溃

转载 作者:可可西里 更新时间:2023-11-01 08:24:27 24 4
gpt4 key购买 nike

我正在尝试将 Excel 2013 嵌入到 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 block 中以查看会发生什么。它永远不会到达 catch block 。 Excel 2013 崩溃并出现臭名昭著的“应用程序已停止工作。向 MS 发送报告”错误。我已经在 Visual Studio 中打开了所有 Win32/COM/C++ 异常(通过 Debug 菜单 > Exceptions 对话框),但这也无济于事。错误对话框中有一个调试 按钮。如果我单击它并打开调试器,我看到的错误消息是“0xC0000005:访问冲突读取位置 0x0000000000000000。”

我还发现,在上面的代码中注释掉 WS.CHILD 行并不能严格地使工作表只读。它只是阻止常见的键盘/鼠标输入到达工作表。但是键盘的上下文菜单键等一些键仍然会到达那里并显示上下文菜单(虽然通过鼠标右键单击不起作用)。同样,我可以通过鼠标与 Office Ribbon 进行交互。似乎只有工作表区域(白色背景的网格)没有接收键盘/鼠标输入。

编辑 2

我只是记得(显然)与 Hans Passant 在他下面的帖子中解释的内容相反,当您创建 Excel VSTO 工作簿项目时,VS2010 本身托管了一个 Excel 实例。虽然我没有 VS2013(完整版)并且无法确认,但我怀疑 VS2013 会对 Excel 2013 VSTO 工作簿项目做同样的事情。考虑到 VS2010 及更高版本本身都是 WPF 应用程序,这如何适应图片?

编辑 3

@acelent 提出的私有(private)接口(interface)理论(参见下面的评论)似乎是正确的。我窥探了 VS2010 托管的 Excel 实例,发现有一个类名 = EXCELI 的新窗口,当我们正常打开 Excel 时它不存在(窗口的正常层次结构是 XLMAIN(应用程序)> XLDESK(工作区区域)> EXCEL7(工作簿))。此外,该工作簿不再作为 ActiveX 对象提供,这曾经是 Office Web Components 库可用时的情况(最后随 Office 2003 一起提供)。所以总而言之,我们似乎走到了死胡同,我将向我的客户建议@Hans 的回答,除非有人在接下来的几个小时内提出实际的工作方法。

最佳答案

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

WS_CHILD 不能按设计工作,Windows 有严格的要求,即父窗口和它的子窗口属于同一个进程。它们在彼此之间传递消息,当子进程试图取消引用属于父进程的指针时,它会崩溃。

Windows 确实有一些对 SetParent() 的 appcompat 支持,这是必需的,因为这通常在 Windows 3.x 程序中完成。具有独立地址空间的进程的概念在该 Windows 版本中完全不存在,因此这在当时不是问题。这在 20 年后仍然正常工作的几率与该过程的行为与 Windows 3.x 应用程序的行为程度成正比。它适用于控制台窗口或像记事本这样的简单应用程序。 Office 2013 应用远远超出简单和 3.x。输入有问题当然是一个标志。你可以修改 AttachThreadInput()尝试解决它,但您很可能会迎面遇到下一个问题,包括它在调试时导致死锁的恶习。

嵌入 Office 应用程序曾经是 Office 中受到强烈支持的功能,Microsoft 有意将它们设计为可嵌入的。底层技术称为 OLE 链接和嵌入。然而,这项技术已被强烈反对。 .NET Framework 有意排除了对它的支持。 Office 2003 是最后一个仍然很好地支持它的版本。麻烦从2007年开始,到2010年彻底报废,再也回不来了。

这里的前进方向恰恰相反。不要嵌入 Office 应用,让 Office 应用嵌入你。强烈支持为 Office 程序编写加载项。

关于c# - Excel 2013 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20344321/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com