COM/ActiveX
DotNetBrowser 不支持将其功能作为 COM 组件或 ActiveX 控件公开。
但如果您需要将 DotNetBrowser 与只能使用 OLE/COM/ActiveX 的应用程序集成,您可以考虑包装您需要的功能,然后将这些包装器公开给该应用程序。 .NET Framework 和最新版本的 .NET(从 .NET Core 3.0 开始)都支持与 COM 库进行互操作。 因此,可以在 VB6、VBA、VBScript 等中访问 DotNetBrowser 提供的所有 Chromium 功能。
以下是对这一想法的一般描述:
- 设计并声明一组公开您所需功能的 COM 接口。 这些接口可以放在一个单独的项目中。 使用
ComVisible
属性来控制特定类和接口的可访问性。 - 在这些接口的实现中,初始化 DotNetBrowser 并执行您需要的所有操作。
- 如果需要,可以使用
ComRegisterFunction
和ComUnregisterFunction
属性自定义程序集注册。 如果您计划注册基于 DotNetBrowser 功能的 ActiveX 控件,这似乎是必要的。 - 构建程序集并使用程序集注册工具 (
regasm.exe
) 对其进行注册。
在此之后,相应的条目将出现在 Windows 注册表中,该包装器将对 COM 客户端可用。
包装 DotNetBrowser 功能并将其公开给 COM 客户端的示例项目的代码在 GitHub 存储库中作为 Visual Studio 项目提供: C#, VB.NET
下文将详细介绍该示例的实现过程,并解释其中最重要的部分。
实现
声明 COM 接口
有几种方法可以在 .NET 中声明 COM 接口。 例如,您可以考虑在类上使用 ClassInterface
属性,向 COM 客户端公开其所有公共方法、属性、字段和事件。 在该示例中,使用了一种不同的方法——整个程序集被标记为ComVisible
,接口被显式声明并公开。 这种方法有助于更好地控制向 COM 公开的内容。 接口实现被声明为内部类。 例如:
接口:
[Guid("D620EC2F-03E8-4C1A-9FF9-3A7B44590F54")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IComEngine
{
[DispId(1)]
void Initialize();
[DispId(2)]
void Dispose();
[DispId(3)]
IComBrowser CreateBrowser();
}
这个示例接口提供了三个方法 - 其中两个可用于控制包装的 IEngine
实例的生命周期,第三个用于创建 IBrowser
实例并将相应的 COM 包装器返回给客户端。
您还可以考虑将 ComVisible
属性应用于特定的类和接口,而不是将其应用于整个程序集。 在这种情况下,只有标有该属性的类和接口才能供 COM 客户端使用。 所有其他公共类型都不会公开。
实现 COM 接口
这是上一节中提到的接口的示例实现:
实现:
[Guid("DAE7A4AC-2D70-4830-81D8-3D7E5D8A7981")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("DotNetBrowser.ComWrapper.Engine")]
public class EngineWrapper : IComEngine
{
private IEngine engine;
private bool initialized;
#region Methods
public IComBrowser CreateBrowser() => new BrowserImpl(engine.CreateBrowser());
public void Dispose()
{
if (initialized)
{
engine?.Dispose();
engine = null;
initialized = false;
}
}
public void Initialize()
{
if (!initialized)
{
engine = EngineFactory.Create(new EngineOptions.Builder
{
RenderingMode = RenderingMode.OffScreen
}.Build());
initialized = true;
}
}
#endregion
}
在本例中,该实现是公开的,并指定了 ProgID - 因此,相应的 coclass 将向 COM 公开,并使用 ProgID 来引用它。
自定义程序集注册
该示例项目还提供了 ComBrowserView
类 - 一个用于 WinForms BrowserView
的包装器,可用作独立的 ActiveX 控件。 为了使其可识别为 ActiveX 控件,需要在相应类型的注册过程中添加一些自定义注册表项。 这可以通过在 ComBrowserView
类中定义两个静态方法并将 ComRegisterFunction
和 ComUnregisterFunction
属性应用于它们来实现:
public partial class ComBrowserView : UserControl, IComBrowserView
{
// ...
[EditorBrowsable(EditorBrowsableState.Never)]
[ComRegisterFunction]
private static void Register(Type t)
{
ControlRegistration.RegisterControl(t);
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ComUnregisterFunction]
private static void Unregister(Type t)
{
ControlRegistration.UnregisterControl(t);
}
}
ControlRegistration.RegisterControl
实现向相应的 CLSID
注册表键添加了几个子键 - 其中最重要的是 Control
键,它允许自定义控件显示在 ActiveX 控件容器中. 其他子键定义了应使用的控制激活方式、工具箱图标、类型库 GUID 等。
构建项目并注册程序集
要在构建期间注册程序集,请在示例项目中启用 “Register for COM Interop” 选项。 这似乎有助于调试执行。
作为结果,TLB 就会自动生成并注册。 清理项目会导致注销所有组件。
请检查您尝试集成的应用程序的位数。 如果您的应用程序是 64 位的,而控件仅为 32 位应用程序注册 (在这种情况下,注册表项是在 HKEY_CLASSES_ROOT\WOW6432Node\
下创建的),则此应用程序将无法访问该控件。 如果应用程序是 32 位的,而控件仅为 64 位应用程序注册,则会出现同样的情况。
总结
所述方法似乎有助于创建解决方案,为使用 COM 对象或嵌入 ActiveX 控件的应用程序提供基于 Chromium 的功能。