Regasm和Com Interop假阴性

我试图通过COM公开我们的库,但似乎比实际问题更多地对抗工具。 无论我如何编写COM暴露类,我都会收到警告:“XXX.dll不包含任何可以为COM互操作注册的类型”(在项目属性中将项目标记为注册为COM互操作)。 即使是下面的简单类(作为已签名并标记为ComVisible(false)的程序集中的唯一类)仍然警告仍然存在:

[Guid("77699130-7D58-4d29-BE18-385871B000D1")] [ComVisible(true)] public interface IExample { string GetText(); void SetText(string text); } [Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")] [ComVisible(true)] public class Example : IExample { private string m_text = "default text"; public string GetText() { return m_text; } public void SetText(string text) { m_text = text; } } 

我试图从输出的命令行运行regasm,很高兴地说“类型注册成功”。 但是,使用/ verbose开关运行时不会显示额外的信息(我似乎记得它列出了名称或者只列出了已注册类型的数量)。 还尝试用/ regfile开关运行regasm来生成一个regfile,它生成这个:

 [HKEY_CLASSES_ROOT\ComExample.Example] @="ComExample.Example" [HKEY_CLASSES_ROOT\ComExample.Example\CLSID] @="{F91E5EE1-D220-43B5-90D1-A48E81C478B7}" [HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}] @="ComExample.Example" [HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32] @="mscoree.dll" "ThreadingModel"="Both" "Class"="ComExample.Example" "Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c" "RuntimeVersion"="v2.0.50727" [HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32\1.0.0.0] "Class"="ComExample.Example" "Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c" "RuntimeVersion"="v2.0.50727" [HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\ProgId] @="ComExample.Example" [HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}] 

我不是任何措施的COM向导,但注册看起来对我有效。 但是,在程序集上运行regasm时,似乎没有任何内容出现在注册表中。

所以我的问题是我是否在我的简单示例中遗漏了一些注册工作,我看到了错误的指示并且注册实际上是正确的,我怎样才能更好地确定COM注册是否真的有效

编辑:使用Kev建议的改动我无法避免来自VS2008的警告,但我实际上可以直接使用regasm在注册表中注册一些东西(仅在VS2008集成的注册表中没有任何内容)。

然后我尝试删除简单的类,所以我有一个空的程序集。 对此运行regasm没有报告任何类型的警告,只有“类型注册成功”。 在我可能错误地暴露给COM的一些其他程序集上运行RegAsm时,我看到“RegAsm:警告RA0000:没有注册类型”等警告。 这里发生了什么,我可以信任除注册表以外的任何内容以及来自regasm的开/关警告吗?

我根据您的代码创建了一个类库项目,如下所示:

在项目属性页面中,选择“签名”选项卡。 选中“签署程序集”复选框,然后从“选择强名称密钥文件:”下拉框中选择

然后我添加了以下类(Example.cs)

 [Guid("77699130-7D58-4d29-BE18-385871B000D1")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] [ComVisible(true)] public interface IExample { [DispId(1)] string GetText(); [DispId(2)] void SetText(string text); } [Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")] [ClassInterface(ClassInterfaceType.None)] [ComVisible(true)] public class Example : IExample { private string m_text = "default text"; [ComVisible(true)] public string GetText() { return m_text; } [ComVisible(true)] public void SetText(string text) { m_text = text; } } 

然后我构建了项目然后删除到命令行,在该命令行中从构建输出DLL。

注册:

regasm.exe COMInteropTesting.dll /register /codebase /tlb

如果您的组件需要可供多个应用程序访问:

gacutil.exe -i COMInteropTesting.dll

这一切在Windows 2003 32位,Windows 2008 32位和Windows 7 64位上运行良好。

但有一个问题是,如果您在64位系统上使用CScript测试组件,则需要运行正确的CScript解释器。 如果您使用32位RegAsm.exe (在C:\Windows\Microsoft.NET\Framework\v2.0.50727 )注册程序集,则需要在c:\Windows\SysWOW64运行32位CScript解释器。