将Excel图表从Excel导入到PowerPoint会导致某些计算机上出现“RPC_E_SERVERFAULT”

时间:2017-10-13 13:10:28

标签: c# .net interop office-interop excel-interop

这是一个令人恼火的。我创建了一种方法将工作簿中的所有Excel图表复制到PowerPoint幻灯片。

public int ImportExcelChartsFromWorkbookToSlides(int startingSlideIndex, string workbookPath, string[] slideTitles, int chartPosTop, int chartPosLeft = 10, int titleWidth = 680, int titleHeight = 20, int titlePosTop = 90, int titlePosLeft = 20, int titleFontSize = 18)
{
    int slideIndex = startingSlideIndex;
    int titleIndex = 0;
    EXCL.Application objExclApp = new EXCL.Application();
    EXCL.Workbook objWorkbook = objExclApp.Workbooks.Open(workbookPath, Editable: false);
    foreach (EXCL.Worksheet objSheet in objWorkbook.Worksheets)
    {
        foreach (EXCL.ChartObject objChart in objSheet.ChartObjects())
        {
            AddBlankSlide(slideIndex);
            AddTextBox(titleWidth.ToString(), titleHeight.ToString(), titlePosTop.ToString(), titlePosLeft.ToString());
            AddTextBoxParagraph(slideTitles[titleIndex], fontSize: titleFontSize.ToString(), useThemeFont: true);

            // Copy Chart from Sheet to Slide
            objChart.CopyPicture();

            PPT.ShapeRange objShapeRange = objSlide.Shapes.Paste();

            objShapeRange.Left = chartPosLeft;
            objShapeRange.Top = chartPosTop;

            slideIndex++;
            titleIndex++;

            Marshal.ReleaseComObject(objChart);
            Marshal.ReleaseComObject(objShapeRange);
        }
        Marshal.ReleaseComObject(objSheet);
    }
    objWorkbook.Close();
    objExclApp.Quit();
    Marshal.ReleaseComObject(objWorkbook);
    Marshal.ReleaseComObject(objExclApp);
    objWorkbook = null;
    objExclApp = null;
    return slideIndex;
}

通常情况下,这在我的机器上完美运行,但有些用户从此方法报告RPC_E_SERVERFAULT。 (HRESULT:0x80010105)

此方法中的某处导致问题。对于不同的办公室安装,内存问题或导致问题的加载项,这或者是一个问题。我已经在其他几台机器上尝试了这个,但它们仍然可以工作。

3 个答案:

答案 0 :(得分:1)

RPC_E_SERVERFAULT很难诊断,很难诊断。 Excel崩溃时出现此错误。没有任何细节,这种崩溃应该由应用程序本身报告。哪个没有发生,更糟糕的是,即使发生了一些相当糟糕的事情,Excel也会继续运行。在您遇到出现此问题的机器上之前,您无法在此类事故中取得任何实际进展。

然而,找到其他受害者并不困难,只有Google" chartobject rpc_e_serverfault"。他们看起来都像你的。减去一个好的解决方案。

我对潜在问题有一个相当好的理论。问题是微软已经设法使Office互操作接口兼容已有19年了。相当令人惊叹的成就,以及每个人都认为理所当然的东西,即使它没有什么微不足道的,但它已经耗尽了气体。作为常见的麻烦制造者,图表值得注意。

看一看IChartObject interface的定义。在Office 2013和2003定义之间来回翻转。并注意神秘的_Copy()方法添加。因为已经存在Copy()方法,所以看起来完全不必要。并且没有记录。

这是一个问题。如果您在VS中使用GoTo Definition查看接口定义,请注意它是接口表中的 second 方法。这是一个很大的问题。它打破了界面的二进制兼容性。

如果您使用Office 2013的互操作库来构建程序并且用户在其计算机上安装了Office 2003(或2007,无法告诉),那么后果是可怕的,那么程序调用中的CopyPicture()调用完全错误的实现方法。推测是Cut(),一种不带参数的方法。这是非常糟糕的,如果方法本身没有内爆,那么堆栈不平衡会导致各种各样的破坏。 RPC_E_SERVERFAULT是预期的结果。

因此,一个可行的理论是,这种炸弹在具有旧Office版本的机器上。除了构建使用2003互操作库的程序的另一个版本并指示IT人员在分发它时要小心,除此之外,你可以做的很少。升级机器是迄今为止简单的解决方法。

答案 1 :(得分:0)

我使用ChartObject.Copy()方法遇到了类似的问题。当我尝试使应用程序可见以查看是否有任何对话框显示时,它实际上最终修复了RPC错误。作为一种解决方法,我在下面打开了excel应用程序,并在运行ChartObject.Copy()和其他操作之前使其短暂可见但最小化。

var excel = new Microsoft.Office.Interop.Excel.Application();
excel.WindowState = Microsoft.Office.Interop.Excel.XlWindowState.xlMinimized;
excel.Visible = true;
var workbooks = excel.Workbooks;
var workbook = workbooks.Open(excelFilePath, ReadOnly: false);
excel.Visible = false;

答案 2 :(得分:0)

在尝试将图表添加到Excel时,(HRESULT的异常:0x80010105(RPC_E_SERVERFAULT))也遇到了这个问题。我发现这是由于我的文件的访问模式设置引起的,这些设置是通过Excel在文件中以及在我自己的代码中进行设置的。

我发布了自己的解决方案(在我的情况下效果很好),在另一个主题中,您可以查看here。我希望这会对外面的人有所帮助!