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

如何注册C# COM Addin使其在64位Microsoft Excel 2019中可见

解决C# COM Addin在64位Excel 2019中不可见的问题

咱们先把核心问题掰明白:32位和64位Windows的注册表是相互隔离的,64位Excel只会读取64位注册表分支,而你之前的注册代码要么没明确指定注册表视图(默认可能走32位分支),要么路径逻辑搞错了。下面给你一套能同时兼容32位和64位Excel的注册方案,一步步来解决:

关键核心点

  1. 64位Excel读取HKLM\Software\Microsoft\Office\Excel\AddIns(64位注册表空间)
  2. 32位Excel读取HKLM\Software\Wow6432Node\Microsoft\Office\Excel\AddIns(32位注册表分支)
  3. 不管是32还是64位,COM组件的CLSID注册都要对应到各自的注册表视图,且InprocServer32的路径要匹配系统位数

正确的注册代码

替换你原来的注册函数,用下面的完整实现:

using Microsoft.Win32;
using System;

[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{
    // 同时注册到64位和32位注册表,兼容两种Excel版本
    RegisterInRegistry(type, RegistryView.Registry64);
    RegisterInRegistry(type, RegistryView.Registry32);
}

[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{
    // 同时从两个注册表分支删除注册信息
    UnregisterFromRegistry(type, RegistryView.Registry64);
    UnregisterFromRegistry(type, RegistryView.Registry32);
}

private static void RegisterInRegistry(Type type, RegistryView registryView)
{
    string clsid = type.GUID.ToString("B").ToUpper();
    RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);

    // 1. 注册CLSID下的Programmable分支,这是.NET COM组件必需的
    string programmablePath = $"CLSID\\{clsid}\\Programmable";
    using (RegistryKey key = baseKey.CreateSubKey(programmablePath))
    {
        // 只需创建分支,无需设置值
    }

    // 2. 设置InprocServer32的默认值,对应位数的mscoree.dll
    string inprocPath = $"CLSID\\{clsid}\\InprocServer32";
    string mscoreePath = registryView == RegistryView.Registry64 
        ? Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\mscoree.dll"
        : Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) + @"\mscoree.dll";
    using (RegistryKey key = baseKey.CreateSubKey(inprocPath))
    {
        key.SetValue("", mscoreePath, RegistryValueKind.String);
        // 必须设置线程模型为Apartment,这是Excel COM Addin的硬性要求
        key.SetValue("ThreadingModel", "Apartment");
    }

    // 3. 注册到Excel AddIns分支,让Excel能识别并显示这个插件
    string addinPath = $"Software\\Microsoft\\Office\\Excel\\AddIns\\{clsid}";
    using (RegistryKey key = baseKey.CreateSubKey(addinPath))
    {
        key.SetValue("FriendlyName", "我的Excel COM插件"); // 替换成你的插件名称
        key.SetValue("Description", "用于测试的基础COM插件"); // 替换成你的插件描述
        key.SetValue("LoadBehavior", 3); // 3=启动时自动加载,2=手动按需加载
    }
}

private static void UnregisterFromRegistry(Type type, RegistryView registryView)
{
    string clsid = type.GUID.ToString("B").ToUpper();
    RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);

    // 删除各分支,忽略不存在的键避免报错
    try { baseKey.DeleteSubKey($"CLSID\\{clsid}\\Programmable", false); } catch { }
    try { baseKey.DeleteSubKeyTree($"CLSID\\{clsid}\\InprocServer32", false); } catch { }
    try { baseKey.DeleteSubKey($"Software\\Microsoft\\Office\\Excel\\AddIns\\{clsid}", false); } catch { }
    try { baseKey.DeleteSubKey($"CLSID\\{clsid}", false); } catch { }
}

代码细节解释

  • 注册表视图指定:通过RegistryView.Registry64和RegistryView.Registry32分别操作两个隔离的注册表空间,确保两种Excel版本都能读到注册信息
  • mscoree.dll路径:64位系统用System文件夹下的版本,32位用SystemX86(即SysWOW64)下的版本,避免路径不匹配导致加载失败
  • LoadBehavior设置:设为3让Excel启动时自动加载插件,你也可以根据需求改成2(手动加载)
  • 线程模型:Apartment是Excel COM Addin的强制要求,不设置会导致插件无法正常加载

额外注意事项

  1. 管理员权限:修改系统注册表需要管理员权限,不管是用VS的「注册COM互操作」功能,还是手动用regasm.exe注册,都要以管理员身份运行
  2. 编译设置:你的项目是AnyCPU,确保VS项目属性→「生成」选项卡中的「注册COM互操作」是勾选状态(如果依赖VS自动注册)
  3. 手动注册命令:如果不用VS自动注册,64位系统下要对应使用64位的regasm.exe,命令示例:
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /codebase YourAddin.dll
    
  4. Excel加载项检查:如果还是看不到插件,打开Excel→「文件」→「选项」→「加载项」→「COM加载项」→「转到」,看看插件是否在列表中,若存在但未勾选,手动勾选即可

按照这个方案操作,你的插件应该就能在64位Excel 2019中正常显示了!

内容的提问来源于stack exchange,提问作者Chams Souidi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:07:30