为什么 regasm 会警告我不要用响亮的名字签约?
如果我想让 .NET 程序集可用作 COM 服务器,我必须添加一组属性,然后使用 regasm
将其注册为 COM 服务器。
如果程序集未使用强名称签名 regasm
,则在使用 /codebase
密钥运行时会显示 RA0000
警告,指出程序集可能干扰同一台计算机上的其他程序集,我应该使用强名称对其进行签名,但注册成功,甚至工作得很好。
AFAIK 强名称旨在防止所谓的 DLL 地狱。但 COM 的目的也是为了防止 DLL 地狱。如果我更改暴露给 COM 的任何接口,我必须更改 GUID 或至少保持二进制兼容性。因此,使用强名称签名似乎并没有添加任何有用的东西 - 没有什么可以阻止我破坏 COM 接口,然后使用相同的密钥对进行签名并拥有成熟的 DLL 地狱。
对于 COM 公开的 .NET 程序集,使用强名称签名有什么用?
If I want to make a .NET assembly usable as a COM server I have to add a set of attributes and then use regasm
to register it as a COM server.
If the assembly is not signed with a strong name regasm
when run with /codebase
key shows a RA0000
warning saying that the assembly could interfere with other assemblies on the same computer and I should sign it with a strong name, but registration succeeds and it even works just fine.
AFAIK strong names are intended to prevent so-called DLL hell. But COM was also meant to prevent DLL hell. If I change any interface exposed to COM I must either change the GUID or at least maintain binary compatibility. So signing with a strong name doesn't seem to add anything useful - nothing prevents me from breaking COM interfaces, then signing with the same keypair and having full-blown DLL hell.
What's the use of signing with as strong name in case of COM-exposed .NET assemblies?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个笨拙的警告。 COM DLL Hell 有两个方面。真正糟糕的是修改公共接口而不是分配新的 GUID。未重新编译的客户端应用程序在调用完全错误的方法或抛出令人讨厌的 AccessViolationException 时往往会崩溃并烧毁,而根本不知道原因可能是什么。
第二种是正确执行所有操作(分配新的 GUID),然后用新版本覆盖现有 DLL。您仍然会导致过时的客户端应用程序崩溃,但使用 E_NOINTERFACE hresult 会更温和地崩溃,该结果会生成非常具体的异常,帮助您诊断原因。但用户并没有感到更高兴。
该场景在 .NET 中有一个现成的解决方案,GAC 支持并行部署具有不同版本号的程序集,以便新旧版本可以共存,并且过时的客户端应用程序仍然对旧版本感到满意。这需要一个响亮的名字。是的,当您使用 /codebase 时,该警告肯定会被抑制,因为这清楚地表明您不会使用 GAC。尽管在使用 /codebase 时稍微调整一下你的鼻子并没有什么坏处。此外,您在测试时永远不会在开发计算机上使用 GAC,但在部署时当然应该考虑它。
It is a clumsy warning. There are two aspects to COM DLL Hell. The really bad one is modifying the public interfaces and not assigning new GUIDs. A client app that wasn't recompiled tends to crash and burn when it calls an entirely wrong method or bombs with a nasty AccessViolationException that gives no clue at all what the cause might be.
The second one is doing everything right (assigning new GUIDs) but then overwriting the existing DLL with the new version. You'll still crash that stale client app but more mildly with an E_NOINTERFACE hresult that generates a pretty specific exception that helps you diagnose the cause. The user isn't any happier though.
That scenario has a ready solution in .NET, the GAC supports side-by-side deployment of assemblies with different version numbers so that both the old and the new version can co-exist and the stale client app continues to be happy with the old version. Which requires a strong name. Yes, that warning could certainly have been suppressed when you use /codebase since that makes it quite clear you are not going to use the GAC. Although it doesn't hurt to tweak your nose a bit at using /codebase. Also, you never use the GAC on your dev machine while testing but certainly should consider it when deploying.
据我所知,COM并不是为了防止DLL地狱,它是Hades本身的深坑。术语“DLL Hell”来自多个库的问题,每个库都具有相同名称的方法。在系统注册表中注册 COM 程序集无助于运行时的解析。
对旨在充当 COM 服务器的程序集进行签名可确保该程序集不会与同一计算机上其他 COM 注册的程序集发生冲突。如果没有签名,如果两个 COM 注册的程序集具有相同名称的方法,则可能会导致问题。
To my knowledge, COM was not meant to prevent DLL hell, it was the pit of Hades itself. The term "DLL Hell" comes from the problem of multiple libraries each with same-named methods. The registration of COM assemblies in the system registry does not help with resolution at runtime.
Signing an assembly that is meant to act as a COM server ensures that the assembly doesn't collide with other COM-registered assemblies on the same computer. Without the signing, if two COM-registered assemblies had methods of the same name, it could cause problems.
强命名主要用于将Dll放入GAC中。因此,您可以在同一台计算机上安全地拥有多个具有相同名称(!)的 Dll 版本,而这对于常规 COM-Dll 来说经常会产生问题。不签署 Dll 将无法对其进行 GAC。因此,您不会立即遇到任何问题,但您没有使用有用的功能,因此您会收到警告。
Strong naming is mainly used to put the Dlls into the GAC. So you can have several versions of the Dll with the same name(!) safely on the same computer, which with regular COM-Dlls often produced issues. Not signing the Dlls removes the ability to GAC it. You don't have any immediate problems because of that but you don't use a useful feature, so you get a warning.