Regasm和Com Interop假阴性

时间:2009-10-30 10:16:20

标签: c# com-interop regasm

我试图通过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的开/关警告吗?

1 个答案:

答案 0 :(得分:2)

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

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

然后我添加了以下课程(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.exeC:\Windows\Microsoft.NET\Framework\v2.0.50727)注册了程序集,那么您需要在c:\Windows\SysWOW64运行32位CScript解释器。