【问题标题】:Creating COM Class in .NET to be used in Excel在 .NET 中创建要在 Excel 中使用的 COM 类
【发布时间】:2014-04-30 02:27:11
【问题描述】:

所以我觉得这是非常基本的,但无论出于何种原因,我都无法让它发挥作用。

我有一个 C# 类,我想通过 COM 在 Excel 中使用它。因此,当 C# 类注册到 ROT(并且我的应用程序正在运行)时,当我在 Excel 中执行 GetObject 时,它应该找出我的类是否有任何正在运行的实例,如果有,则返回该实例使用的 Excel。我的问题是,我收到 429 错误 - 它找不到类:(

我不想只贴一堵代码墙(除非有人要求),但我在我的 .exe 上做了一个regasm /codebase,其中包含我想在 Excel 中使用的 COM 可见类。我还指定了自己的 GUID 和 ProgID,ProgID 是我在 Excel 中用来获取对象的。

大部分代码是由其他人编写的,我必须弄清楚如何修复它,所以下面的代码 sn-ps 是我不知道他们做什么但可能是有用的附加信息:

// this gets called before my class (MyApp) is made
RegistrationServices services = new RegistrationServices();
return services.RegisterTypeForComClients(typeof(MyApp), RegistrationClassContext.LocalServer, RegistrationConnectionType.MultipleUse);

// this gets called right after my class (MyApp) is made
if (MyApp == null) return;
Guid guid = typeof(MyApp).GUID;
RegisterActiveObject(MyApp, ref guid, 0, out _RegActiveObjectKey);

这里只是一些关于课程的信息,如果有用的话:

[Guid("FDDBEB42-9E44-45fb-806B-EA535E2947F2")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("MyExe.MyApp")]
[ComVisible(true)]
public class MyApp : IDisposable
{
    // ...
}

编辑:我什至使用以下代码在 ROT 中明确注册了我的课程:

IRunningObjectTable rot = null;
IMoniker pMoniker = null;
string filename = string.Empty;
int retVal = GetRunningObjectTable(0, out rot);
retVal = CreateFileMoniker(filename, out pMoniker);
retVal = rot.Register(1, _MyApp, pMoniker);

【问题讨论】:

  • 您是否考虑过使用 InterOp...? .Net 有大量示例来支持 Microsoft.Interop

标签: c# excel com vba


【解决方案1】:

我在我的 .exe 上做了 regasm /codebase

这并没有达到你希望的效果。 Regasm 专门注册 in-process 服务器,它们通常具有 .dll 扩展名。您的文件具有 .exe 扩展名这一事实没有任何区别。 CLR 不会将它们与具有 .dll 扩展名的程序集区别对待。 .NET 程序集有一个显示名称,与文件名相同。文件扩展名不是程序集全名的一部分,当要求加载程序集时,CLR 将首先查找 .exe,然后查找 .dll。

所以你有一个先有鸡还是先有蛋的问题,Excel 将不会加载你的程序集,直到它创建了你创建的类之一的对象 [ComVisible]。必然地,该对象永远不会出现在 ROT 中,您的程序集还没有注册过。

ROT 通常只有在两个独立的进程相互通信时才有用。换句话说,当您自己启动 EXE 时。在 .NET 中创建进程外服务器是一件非常尴尬的事情,您必须使用 COM+ 托管并从 ServicedComponent 派生您的类。

【讨论】:

  • 谢谢汉斯。我实际上能够通过在我的 C# 代码中执行自定义注册步骤来解决这个问题。通过在方法上使用属性[ComRegisterFunction],我在注册表中创建了LocalServer32 子键,并删除了InprocServer32 子键。它现在连接!
  • 嗯,非常糟糕。不会改变我的答案,somebody 仍然需要启动服务器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 2020-11-05
  • 2013-10-10
  • 2010-09-21
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多