默认情况下COM组件是要在注册表注册的,但是这会引起管理上的问题……
Simplify App Deployment with ClickOnce and Registration-Free COM
全局注册的COM会引起一个叫DLL Hell的问题。
.NET中是通过Global Assembly Cache来管理配装件的
Reg-Free COM看起来在WinXP中就有。需要一个XML宣单(manifest)来记录那些本来需要放在注册表中的信息。这个宣单是给操作系统看的(具体为Native Assembly Loader)。
WindowsApplication1.exe的宣单必须在同一目录,名字为WindowsApplication1.exe.manifest。宣单随应用程序一起加载(CreateProcess的早期),于是在执行前就知道其内容了。操作系统会构建一张表,在CoCreateInstance的时候会优先查询这个表。
VS2005中每个COM引用有一个属性叫做Isolated,默认为False。设为True时支持Reg-Free COM。当VS看见Isolated时,会为其扫描生成manifest。
文章后部讲了一个VB写成的Reg-Free COM的例子。
Registration-free COM
如果不通过CoCreateInstance,那么连Reg-Free COM都不需要的。
- 定位到COM组件的DLL
- 通过LoadLibrary加载之
- 通过GetProcAddress定位到DllGetClassObject
- 通过执行DllGetClassObject获得IClassFactory
- 通过调用IClassFactory::CreateInstances
简单地说,就是不需要操作系统为你寻找COM组件的接口指针位置。
Enhancing Non-packaged Desktop Apps using Windows Runtime Components
Win10 1903开始支持无封包桌面应用对自定义(第三方)WinRT组件的使用。因为使用自定义组件需要封包标识,无法把组件注册到系统中。此前只支持在有封包应用中使用。
解决额手段时引入Reg-free WinRT,跟Registration-free COM一个慨念。也就是在Win32-style application.manifest,而不是在系统注册表中宣告组件。
这么做的好处之一是可以使用UWP XAML Islands。
机制上,在Win32-style application.manifest引入了一个新的activatableClass
元素,用于指明WinRT标类。示例如下:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<file name="WinRTComponent.dll">
<activatableClass
name="WinRTComponent.Class1"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
<activatableClass
name="WinRTComponent.Class2"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
文中介绍了两个例子:
- C++的:https://github.com/Microsoft/RegFree_WinRT/tree/master/Cpp
- C#的:https://github.com/Microsoft/RegFree_WinRT/tree/master/CS
其他例子:
- https://github.com/marb2000/XamlIslands/tree/master/19H1_Insider_Samples/CppWin32App_With_Island
- https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp
其他参考
- How to: Build Registration-Free COM Components
- https://en.wikipedia.org/wiki/Component_Object_Model
- https://github.com/microsoft/xlang/tree/master/src/UndockedRegFreeWinRT
- https://github.com/microsoft/xlang
- Google “visual studio c++ reg free com”
- [C++/WinRT] loading a Windows Runtime Component (reg free) written in C#
- Registration-Free WinRT component for DLL
- Registration-Free COM Interop
(完)
2022-03-12更新
- [Undocked RegFree WinRT - Provides access to user-defined WinRT types for versions of Windows prior to Windows 10 May 2019 update.] (https://github.com/microsoft/xlang/tree/master/src/UndockedRegFreeWinRT)
(更新完0