COMLicenceFinder:一个能够检索 ActiveX 控件运行时许可证文本的小工具
解释了如何在脚本中使用ActiveX控件来获取其运行时许可证。
引言
使用脚本(VBScript、JScript)进行编程是一种相当愉快的体验,您甚至可以使用脚本组件开发基于脚本的应用程序。大家都知道这类编程的强大之处,可以利用ActiveX控件,但如果您尝试部署一个使用标准Microsoft ActiveX控件(例如,用于串行通信的MsComm)的脚本,那么您将不得不克服一个令人讨厌的问题:许多此类控件都需要运行时许可证才能在最终用户PC上工作。顺便说一下,Visual C++和Visual Basic环境会自动为标准应用程序提供已部署组件的运行时许可证,但对于脚本语言来说,情况完全不同:您必须“手动”提供此信息。我知道一些解决方法,即围绕目标ActiveX控件构建包装器,然而,在本文中我将展示一种直接的方法。您需要处理两个不同的问题:
- 了解(获取)运行时许可证文本。
- 在脚本中提供此文本。
背景
您应该知道如何在脚本中使用ActiveX控件(请参阅MSDN)。还需要对COM有 general 知识(有很多关于COM的书籍:inside COM、essential COM等)。
使用应用程序
加载时,ComLicenceFinder
会查询注册表以获取并列出PC上所有可用的ActiveX控件。如果您对其中任何一个的运行时许可证信息感兴趣,首先选择它,然后单击鼠标右键,并在新出现的上下文菜单中选择Get info(获取信息)项。该应用程序将尝试:
- 查询所选ActiveX控件的类对象(或类工厂)的
IClassFactory
接口指针。 - 通过已获得的指针查询一个新的指针,这次是
IClassFactory2
接口。 - 调用
IClassFactory2::GetLicInfo
方法。 - 调用
IClassFactory2::RequestLicKey
方法。
在成功完成**所有**上述步骤后,您将获得所需的运行时许可证文本;但是,每个步骤的结果都报告在列表视图的一个字段中,该字段应解释如下:
字段 | 类型 | 描述 | 注意 |
---|---|---|---|
名称 | 字符串 | ActiveX控件的友好名称,在注册表中找到的名称 | - |
CLSID | 字符串 | ActiveX控件的类ID。 | 这是ActiveX控件的唯一标识符,任何需要该控件的脚本都必须使用它。 |
可创建 | 是/否 | 如果成功获取IClassFactory 接口,则为Yes |
如果为No ,则该项可能对应于注册表中的错误条目 |
许可证信息 | 是/否 | 如果存在运行时许可证,则为Yes |
如果不存在运行时许可证,您仍然可以尝试使用ActiveX控件,*也许它根本不需要许可证。* |
许可证文本 | 字符串 | 运行时许可证文本 | - |
相关代码包含在GetLicenceInfo
函数中(我已删除一些无聊的部分,例如插入列表视图)
// Query for the Class Object IClassFactory interface pointer HRESULT hr = CoGetClassObject(uuid, CLSCTX_ALL, NULL, IID_IClassFactory, (void**)&pCF); if ( FAILED(hr) ) return; // Now query for the IClassFactory2 interface pointer. hr = pCF->QueryInterface(IID_IClassFactory2, (void**)& pCF2); pCF->Release(); // Call the GetLicInfo method to obtain licence info if ( FAILED(hr) ) return; LICINFO licInfo; licInfo.cbLicInfo = sizeof(licInfo); hr = pCF2->GetLicInfo(&licInfo); if ( FAILED(hr) ) { pCF2->Release(); return; } // Is a runtime key available ? fSuccess = (licInfo.fRuntimeKeyAvail == TRUE && licInfo.fLicVerified == TRUE ) ? true : false; if (! fSuccess) { pCF2->Release(); return; } // Query the Runtime Key (i.e. the runtime licence text) hr= pCF2->RequestLicKey( 0, & bstrLic ); if ( FAILED(hr) ) { pCF2->Release(); return; } ZeroMemory(buf, BUFSIZE); // We need a ASCII string fSuccess = WideCharToMultiByte(CP_ACP, 0, bstrLic, SysStringLen(bstrLic), buf, BUFSIZE, NULL, NULL) == 0 ? false : true; pCF2->Release(); SysFreeString(bstrLic); if (! fSuccess ) { return; }
关注点
上下文菜单中的Copy(复制)项可用于将相关信息(即名称、CLSID、许可证文本)复制到剪贴板(然后将其*粘贴*到您的脚本中…)。
另一方面,上下文菜单中的Save(保存)项将列表视图的全部(当前)内容保存到选定的XML文件中(您PC上所有ActiveX控件CLSID的查找表?!)。
值得注意的是,该应用程序只需要链接*Rpcrt4.lib*来使用*UuidFromString*函数。
历史
- 首次发布。