如何注册.NET程序集代替现有的COM服务器?

时间:2014-09-03 15:00:26

标签: c# windows com

我必须处理一个COM类,它或多或少是一个更大系统的黑盒组件。此类来自COM EXE,并在系统中注册了已知的AppID和Typelib ID。

为了调试和记录,我创建了一个mock类,它在C#中实现了这个相同的接口。问题是:如何注册我的程序集,以便在调用应用程序尝试实例化接口时,它将实例化我的类?

使用更多信息进行编辑:

我有以下内容:类型库的GUID,实现类的GUID,类的ProgID GUID。导入类型库后,我执行了以下操作:

[ComVisible(true)]
[ProgId("The.ProgId.Of.The.Old.Class")]
[Guid("{the guid of the old class}")]
public class MockImplementation : ISomething 
{
    // ...
}

我尝试像这样注册我的课程:

regasm /codebase myassembly.exe

然而,没有任何反应。应用程序仍然实例化旧类。我做错了什么?

1 个答案:

答案 0 :(得分:1)

  

此课程来自COM EXE

请记住,您编写了进程外COM服务器的真正替代品。您的替代品是进程内服务器。一个DLL。它们的位置存储在不同的注册表项中,out-of-proc使用LocalServer32键,in-proc使用InProcServer32键。我无法看到您的测试代码来判断将使用哪一个。但显然这是错误的:)

Regasm.exe也是一个可能的麻烦点。请记住,它有两个版本。来自c:\ windows \ microsoft.net \ framework的32位版本写入32位注册表项,来自framework64的64位版本写入64位注册表项。两者都工作正常,.NET代码可以在任一模式下运行,但您的测试应用程序将只使用其中一个。取决于配置,VS测试运行器默认为32位模式。

这里的基本故障排除工具是SysInternals'进程监视器。很高兴看到现有COM服务器和您的替代品都使用了哪些注册表项。作为一个起点,观察现有服务器注册本身,以便您知道完全哪些注册表项是重要的。通常通过使用/ regserver命令行选项运行EXE来完成。记下您正在编写的CLSID,Interface和TypeLib键。

然后在运行Regasm.exe时再次执行此操作,将您看到的内容与您记下的内容进行比较。请务必使用/ codebase选项,这样您就不必依赖GAC。是否使用/ tlb选项是判断调用。首先使用它来比较键。当然,您现在期望看到InProcServer32被编写而不是LocalServer32,这是不可避免的。

然后再次执行此操作,现在运行您的测试应用程序。将此次读取的内容与您的笔记进行比较。您可能必须敲击LocalServer32密钥以防止它被使用。或者更好的是,完全取消注册旧服务器,使其不会妨碍,通常使用/ unregserver选项。在此之后,您必须重新运行Regasm.exe以将密钥放回原位。