.net “注册 COM 互操作”与“使程序集 COM 可见”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3699767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:43:35  来源:igfitidea点击:

"Register for COM Interop" vs "Make assembly COM visible"

.netvisual-studiocom-interopcompiler-options

提问by A9S6

What is the real difference between these two options? What I know is:

这两个选项之间的真正区别是什么?我所知道的是:

Register for COM Interop
This options executes regasm on the assembly and registers the assembly as an COM component(or maybe not) in the registry with all COM like registry entries. Does this step generates a TLB file? What else is done?

注册 COM 互操作
此选项在程序集上执行 regasm,并将程序集注册为注册表中的 COM 组件(或可能不是),所有 COM 类似注册表项。此步骤是否生成 TLB 文件?还做了什么?

Sometimes I see a tlb is generated when I compile the project but sometimes not, why is this?

有时我在编译项目时看到生成了一个tlb,但有时却没有,这是为什么?

Make assembly COM visible
What effect does this one has on an assembly? If I have the following type inside this assembly, do I still need to specify the "Make assembly COM Visible" even though my type is marked as ComVisible?

使程序集 COM 可见
这对程序集有什么影响?如果我在这个程序集中有以下类型,即使我的类型被标记为 ComVisible,我是否仍然需要指定“使程序集 COM 可见”?

[GuidAttribute("02810C22-3FF2-4fc2-A7FD-5E103446DEB0"), ComVisible(true)]
public interface IMyInterface
{
}

回答by Hans Passant

"Make assembly COM visible" is a big hammer to make allpublic types in the assembly [ComVisible]. Rarely desirable, you will want to select the specific types that you want to be visible, like you did in your snippet.

“使程序集COM可见”是使程序集中所有公共类型[ComVisible]的大锤。很少需要,您会想要选择要显示的特定类型,就像您在代码段中所做的那样。

After the assembly is built, it needs to be registered so that a COM client can find it back. Which only uses a number to identify the object he wants to create, the GUID, an extra lookup is necessary to find out what DLL implements it. Registering involves writing keys in the HKLM\Software\Classes\CLSID\{guid}portion of the registry. You can do it yourself by running Regasm.exe /codebase /tlbor you can leave it up to the build system to do it automatically after building the assembly.

程序集构建完成后,需要对其进行注册,以便 COM 客户端可以找到它。它只使用一个数字来标识他想要创建的对象,即 GUID,需要额外的查找才能找出实现它的 DLL。注册涉及HKLM\Software\Classes\CLSID\{guid}在注册表部分写入密钥。您可以通过运行自己完成,Regasm.exe /codebase /tlb也可以让构建系统在构建程序集后自动完成。

Which is what "Register for COM interop" does. It is desirable since it ensures that the old copy of the DLL gets unregistered automatically before it is overwritten, that prevents registry pollution. VS needs to run elevated to have write access to those registry keys, one reason for making it optional. Or you just don't want to register it, common on build servers. I can't comment on why you'd sometimes not get the .tlb without more diagnostics.

这就是“注册 COM 互操作”的作用。这是可取的,因为它确保 DLL 的旧副本在被覆盖之前自动取消注册,从而防止注册表污染。VS 需要运行提升才能对这些注册表项进行写访问,这是使其成为可选的原因之一。或者您只是不想注册它,这在构建服务器上很常见。我无法评论为什么您有时在没有更多诊断的情况下无法获得 .tlb。

回答by César Qüeb

In addition to the accepted answer, the .tlbfile is not created if the types or methods changed without first removing the corresponding record from the Windows's Registry (or closing the application or service that use the library), using the /U option of the RegAsm utility:

除了接受的答案外,. 如果使用 RegAsm 实用程序的 /U 选项未首先从 Windows 注册表中删除相应记录(或关闭使用该库的应用程序或服务)而更改了类型或方法,则不会创建.tlb文件:

Regasm.exe yourlibrary.dll /codebase /tlb /u

Also, it is important to mention that the registry for consumption of the library as COM, will only work in the development machine if it is compiled using the options Register for COM interopand Make assembly COM-Visible. It is necessary to register it manually in each destination computer using the indicated command line or, generating an script that is executed when the library is installed.

此外,值得一提的是,用于将库作为 COM 使用的注册表仅在使用Register for COM interopMake assembly COM-Visible选项编译时才能在开发机器中工作。有必要使用指定的命令行在每台目标计算机中手动注册它,或者生成在安装库时执行的脚本。