You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用Workbooks.Open加载Excel插件(.xla/.xlam)失败,报错RPC_E_SERVERFAULT

解决C#操作Excel循环时出现RPC_E_SERVERFAULT(0x80010105)的问题

这个RPC_E_SERVERFAULT错误本质是Excel COM服务端内部触发了未处理异常,你的代码里存在几个明显的问题,导致操作不稳定,以下是具体修复方案:

核心问题分析

  1. 重复加载AddIn且操作冗余:代码里两次重复打开并重置REFPROP.XLA和REFPROP_Ribbon.xlam的Installed状态,这会导致Excel内部加载状态混乱,触发服务端异常。
  2. 不可靠的等待方式:Thread.Sleep(3000)是强制阻塞线程,但无法保证Excel已经完成加载/初始化操作,经常会出现代码继续执行但Excel还没就绪的情况。
  3. COM对象未正确释放:没有显式释放Excel相关的COM对象,容易导致内存泄漏和残留Excel进程,干扰后续循环操作。
  4. Office COM线程安全问题:如果你的循环是在多线程环境下执行,Office COM组件不支持跨线程调用,必然会出现随机异常。

具体修复步骤

1. 优化AddIn加载逻辑,避免重复操作

只需要加载一次AddIn,并且先检查是否已加载,再执行安装/重置操作:

// 封装AddIn加载方法,避免重复代码
private void LoadRefPropAddIns(Excel.Application excelApp)
{
    string[] addInPaths = { 
        @"C:\Program Files (x86)\REFPROP\REFPROP.XLA",
        @"C:\Program Files (x86)\REFPROP\REFPROP_Ribbon.xlam"
    };

    foreach (string path in addInPaths)
    {
        string addInName = System.IO.Path.GetFileName(path);
        Excel.AddIn addIn = null;
        try
        {
            addIn = excelApp.AddIns.Item(addInName);
        }
        catch
        {
            // AddIn不在列表中,尝试打开加载
            excelApp.Workbooks.Open(path);
            addIn = excelApp.AddIns.Item(addInName);
        }

        if (addIn != null && !addIn.Installed)
        {
            addIn.Installed = true;
        }
    }
}

2. 替换Thread.Sleep为Excel原生等待方法

使用Excel的Wait方法,等待Excel内部操作完成,而不是固定睡眠:

// 等待3秒,直到Excel就绪
excelApp.Wait(DateTime.Now.AddSeconds(3));

3. 严格管理COM对象释放

每次操作完成后,必须显式释放所有Excel相关的COM对象,避免泄漏:

// 使用完Workbook后释放
if (ExcelBook != null)
{
    ExcelBook.Close(false);
    Marshal.ReleaseComObject(ExcelBook);
    ExcelBook = null;
}

// 最后退出Excel并释放Application对象
if (ExcelApp != null)
{
    ExcelApp.Quit();
    Marshal.ReleaseComObject(ExcelApp);
}
GC.Collect();
GC.WaitForPendingFinalizers();

4. 确保单线程执行所有Excel操作

Office COM组件仅支持STA线程,所有操作必须在创建Excel.Application的同一个线程中执行,禁止跨线程调用。如果是循环执行,确保每次循环都在同一个STA线程内,或者每次循环创建新的Excel实例并正确释放。

5. 清理残留Excel进程

在循环开始前,检查并杀掉所有残留的Excel进程,避免干扰:

foreach (Process proc in Process.GetProcessesByName("EXCEL"))
{
    proc.Kill();
}

修改后的完整Open方法示例

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;

public bool Opened = false;
public string ExcelPath = "你的目标Excel路径";

public void Open()
{
    Excel.Application ExcelApp = null;
    Excel.Workbook ExcelBook = null;
    try
    {
        // 清理残留Excel进程
        foreach (Process proc in Process.GetProcessesByName("EXCEL"))
        {
            proc.Kill();
        }

        ExcelApp = new Excel.Application();
        // 加载AddIn,仅执行一次
        LoadRefPropAddIns(ExcelApp);
        
        // 等待Excel就绪
        ExcelApp.Wait(DateTime.Now.AddSeconds(3));

        // 打开目标工作簿
        ExcelBook = ExcelApp.Workbooks.Open(ExcelPath);
        Opened = true;

        // 等待工作簿加载完成
        ExcelApp.Wait(DateTime.Now.AddSeconds(3));

        // 这里添加运行宏的代码
        // ExcelApp.Run("你的宏名称");

    }
    catch (Exception e)
    {
        // 可添加日志记录逻辑
        throw;
    }
    finally
    {
        // 释放所有COM对象
        if (ExcelBook != null)
        {
            ExcelBook.Close(false);
            Marshal.ReleaseComObject(ExcelBook);
        }
        if (ExcelApp != null)
        {
            ExcelApp.Quit();
            Marshal.ReleaseComObject(ExcelApp);
        }
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

private void LoadRefPropAddIns(Excel.Application excelApp)
{
    string[] addInPaths = { 
        @"C:\Program Files (x86)\REFPROP\REFPROP.XLA",
        @"C:\Program Files (x86)\REFPROP\REFPROP_Ribbon.xlam"
    };

    foreach (string path in addInPaths)
    {
        string addInName = System.IO.Path.GetFileName(path);
        Excel.AddIn addIn = null;
        try
        {
            addIn = excelApp.AddIns.Item(addInName);
        }
        catch
        {
            // AddIn不在列表中,尝试打开加载
            excelApp.Workbooks.Open(path);
            addIn = excelApp.AddIns.Item(addInName);
        }

        if (addIn != null && !addIn.Installed)
        {
            addIn.Installed = true;
        }
    }
}

内容的提问来源于stack exchange,提问作者Reut Yfrach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:05:21