代码之家  ›  专栏  ›  技术社区  ›  soren.enemaerke

regasm和com interop错误否定

  •  1
  • soren.enemaerke  · 技术社区  · 16 年前

    我正试图通过COM公开我们的库,但似乎比实际问题更难对付这些工具。无论我如何编写我的COM公开类,我都会收到警告:“xxx.dll不包含任何可以为COM互操作注册的类型”(在项目属性中将Project标记为“为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没有报告任何类型的警告,只有“成功注册的类型”。在我的一些其他程序集上运行regasm时,我看到类似“regasm:warning ra0000:no types were registered”的警告,这些程序集可能错误地暴露于COM。这里发生了什么,除了注册表,我可以信任任何东西吗?关于Regasm的开/关警告呢?

    1 回复  |  直到 16 年前
        1
  •  2
  •   erlando    16 年前

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

    在“项目属性”页中,选择“签名”选项卡。选中“为程序集签名”复选框并选择 <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

    这在Windows2003 32位、Windows2008 32位和Windows7 64位上都很好地工作。

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