65.9K
CodeProject 正在变化。 阅读更多。
Home

LicenceProvider

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.28/5 (11投票s)

2006年10月26日

CPOL

2分钟阅读

viewsIcon

41587

downloadIcon

1037

一个小的 COM 组件 (DLL),允许脚本提供 ActiveX 控件的运行时许可文本。

引言

如果您尝试在脚本 (JScript, VBScript, 脚本组件) 中嵌入 Microsoft ActiveX 控件,例如 MSComm (用于串口通信),那么您必须提供其运行时许可文本 (或密钥) 才能使其在未授权的最终用户机器上工作 (是的,只有在您计划部署脚本时才会遇到这类问题)。我制作了一个非常小的 COM 组件 (由 DLL 托管),能够提供此类许可。当然,您需要知道目标 ActiveX 控件的运行时许可文本 (我也开发了一个应用程序来发现授权机器上的此类文本,即安装了 Visual Studio 的 PC,请参阅我的关于 COMLicenceFinder 的文章)。

背景

您应该知道如何在脚本中使用 ActiveX 控件 (请参阅 MSDN)。对 COM 的一般了解也是可取的 (有很多关于 COM 的书籍:Inside COM, Essential COM 等)。

使用 LicenceProvider COM 组件

首先,您必须在目标机器上注册 LicenceProvider 组件和您的脚本使用的 MS ActiveX 控件。然后,您可以调用 LicenceProvider 对象的 Provide 方法来获取控件的实例。

var objSerial;
// Create the LicenceProvider object
var lp = new ActiveXObject("LicenceProvider.LicProvider");
// Use the LicenceProvider object to obtain an instance
// of the MsComm ActiveX, by providing a Runtime Licence text.
// Passing MsComm CLSID & Runtime
// Licence Text as argumens. 
objSerial = lp.Provide("{648A5600-2C6E-101B-82B6-000000000014}", 
                       "Copyright (c) 1994 ");

上面的示例代码 (JScript) 只是演示了如何通过 LicenceProvider 对象的 Provide 方法获取 MSComm 的实例,并提供运行时许可。

关注点

您需要使用 COM 组件作为 LicenceProvider,因为我知道的唯一方法是请求控件的 IClassFactory2 接口的 CreateInstanceLic 成员来获取任何此类 ActiveX 控件的运行时许可实例,而后者不能直接被脚本访问。因此,LicenceProvider 最终是一个将 VTABLE 绑定到自动化客户端 (如脚本) 使用的 DISPATCH 的 *适配器*。执行的步骤如下:
  1. 获取 ActiveX 控件类对象 IClassFactory 接口的指针。
  2. 使用获取的指针,请求另一个指针,这次指向 IClassFactory2 接口。
  3. 调用 IClassFactory2::CreateInstanceLic 来获取 ActiveX 控件的实例 (实际上,是其 IUnknown 接口的指针)。
  4. 通过 IUnknownQueryInterface 方法请求 IDispatch 接口指针。

以下示例代码展示了这些步骤:

if ( UuidFromString((unsigned char *)
       (pCLSIDBegin+1), &uuid) != RPC_S_OK )
    return E_FAIL;
HRESULT hr = CoGetClassObject(uuid, CLSCTX_ALL, 
             NULL, IID_IClassFactory, (void**)&pCF);
if ( FAILED(hr) ) return E_FAIL;
hr = pCF->QueryInterface(IID_IClassFactory2, (void **)&pCF2);
pCF->Release();
if ( FAILED(hr)) return E_FAIL;
IUnknown * pObj;
hr = pCF2->CreateInstanceLic(NULL,NULL, IID_IUnknown , 
                             lictext, (void **)&pObj); 
pCF2->Release();
if ( FAILED(hr)) return E_FAIL;
pObj->QueryInterface(IID_IDispatch, (void **) pObject);

DISPATCH 到 VTABLE 的映射的魔力是由组件的双接口 (感谢 ATL) 实现的。

历史

  • 2006 年 10 月 26 日 - 首次发布。
© . All rights reserved.