Regasm 和 Com Interop 漏报

发布于 2024-08-09 08:11:29 字数 2263 浏览 2 评论 0原文

我试图通过 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 不会报告任何类型的警告,仅报告“类型注册成功”。在我的其他一些程序集上运行 RegAsm 时,我看到类似“RegAsm:警告 RA0000:未注册类型”的警告,这些程序集可能会错误地暴露给 COM。这是怎么回事,除了注册表之外我可以相信任何东西吗?重高潮的开/关警告又如何呢?

I'm attempting to expose our library via COM but seem to be fighting the tools more than the actual problem. Regardless of how I write my COM exposed class I get the warning: "XXX.dll does not contain any types that can be registered for COM interop" (marked project as Register for COM interop in the project properties). Even the simple class below (as the only class in an assembly that is signed and marked with ComVisible(false)) still warning persists:

  [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;
    }
  }

I've tried to run regasm from the command line on the output which gladly states "Types registered successfully". However, running with the /verbose switch no extra information is displayed (I seem to recall that it lists the name or perhaps just the number of registered types). Also tried running regasm with the /regfile switch to generate a regfile which generates this:

[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}]

I'm no COM wizard of any measure but the registration looks valid to me. However, nothing seems to appear in the registry when running regasm on the assembly.

So my question is whether I'm missing something in my simple example to have the registration work, am I seeing false indications and is the registration actually correct and how can I better determine if the COM registration actually works

EDIT:
Using the alterations suggested by Kev I could not avoid the warnings from VS2008 but I could actually get something registered in the registry using regasm directly (nothing in the registry from just the VS2008 integration).

I then tried to remove the simple class so I had an empty assembly. Running regasm on this did not report any sort of warnings, only "Types registered successfully". I see warnings like "RegAsm : warning RA0000 : No types were registered" when running RegAsm on some of my other assemblies which may be incorrectly exposed to COM. What is going on here, can I trust anything except the registry and what about the on/off warnings from regasm?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无人问我粥可暖 2024-08-16 08:11:29

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

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

然后,我添加了以下类(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),那么您需要运行 32 位 CScript解释器位于c:\Windows\SysWOW64

I created a class library project based on your code as follows:

In the project properties page, select the Signing tab. Check the 'Sign the assembly' checkbox and select <New...> from the 'Choose a strong name key file:' drop down box.

I then added the following class (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;
    }
}

I then built the project then dropped to a command line where the DLL was output from the build.

To register:

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

If your component needs to be accessible to multiple applications:

gacutil.exe -i COMInteropTesting.dll

This all worked fine on Windows 2003 32bit, Windows 2008 32bit and Windows 7 64 bit.

One gotcha though is that if you're testing the component with say CScript on a 64 bit system, you need to run the correct CScript interpreter. If you registered the assembly using 32bit RegAsm.exe (at C:\Windows\Microsoft.NET\Framework\v2.0.50727) then you need to run the 32 bit CScript interpreter at c:\Windows\SysWOW64.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文