Visual Studio 会为您生成一个所谓的互操作库。这意味着如果您引用一个被调用的库,MyCOMLib.dll
它将生成一个名为MyComLib.Interop.dll
. 此程序集包含您从 .NET 应用程序实例化的.NET 包装器对象(所谓的Runtime Callable Wrappers )。您可以使用TlbImp.exe -Tool 自行生成此互操作库。
因此,您实际实例化的不是实际的 COM 对象,而是充当这些 COM 对象的某种代理的 .NET 对象。在内部,他们正在为您调用CoCreateInstance
orCoCreateInstanceEx
和 COM 类工厂。他们还管理这些对象的内存处理。(您可以使用 来影响此管理Marshal.ReleaseComObject
,但您应该注意到这可能很危险)。
这意味着您的应用程序总是与这些互操作程序集一起发布。如果这些程序集不存在(并且您已使用Project References引用了它们),则应用程序将不会运行(它将在启动时引发异常)。如果程序集可以加载到您应用程序的AppDomain中,则在您创建互操作类型对象之前不会有任何问题。RCW 将CoCreateInstance
/CoCreateInstanceEx
与 CLSID 一起调用(互操作程序集通过 TlbImp.exe 工具知道这一点)。如果在注册表中找不到这些类 ID,您的应用程序将引发运行时异常。
检查库是否存在的一个好方法是在应用程序设置期间检查唯一的库 ID 和版本。这些存储在注册表中。您需要知道库的 GUID 和版本,然后您会在HKLM\Software\Classes\TypeLib\{Guid}\{Version}
.
最好的方法是将您的应用程序与自行安装库的第 3 方可再发行包一起交付。这也确保了其他应用程序不会删除第 3 方类型库。这就是微软使用 Visual C++ 库或 DirectX 的方式。