作者:zyl910。
这是一个小工具,枚举ActiveX控件的 CLSID 和 implemented/required CATIDs。可用来帮助分析ActiveX控件部署问题。
一、代码
全部代码——
View Code
#include <stddef.h> #include <stdio.h> #include <tchar.h> #include <locale.h> #include <Windows.h> #include <crtdbg.h> #include <comcat.h> #include <atlconv.h> void doenumactivex(void); int _show_catid = FALSE; // 获取程序位数(被编译为多少位的代码) int GetProgramBits() { return sizeof(int*) * 8; } int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL, ""); // 使用系统当前代码页. _tprintf(_T("enumactivex v1.00 (%dbit)\n\n"), GetProgramBits()); CoInitialize(NULL); _show_catid = (argc>1); // 当带有命令行参数时,显示 implemented/required CATIDs。 doenumactivex(); CoUninitialize(); return 0; } void fprint_GUID(FILE *stream, REFGUID refguid) { #define GUID_STRING_LEN 50 OLECHAR szGuid[GUID_STRING_LEN]; int nCount = ::StringFromGUID2(refguid, szGuid, GUID_STRING_LEN); if (nCount<=0 || nCount>=GUID_STRING_LEN) return; szGuid[nCount] = 0; _ftprintf(stream, _T("%ls"), szGuid); // 因OLECHAR实际上是UTF16编码的字符串. } // 枚举ActiveX控件. void doenumactivex(void) { // 参考了: http://hi.baidu.com/dakzjbwlqctuyzr/item/46d199e81f81f312595dd86c LCID lcid = GetSystemDefaultLCID(); // // The Component Category Manager implemented by System // implements this interface ICatInformation* pCatInfo = NULL; // Create an instance of standard Component Category Manager HRESULT hr = CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatInformation, (void **)&pCatInfo); // Increase ref count on interface pCatInfo->AddRef(); // IEnumGUID interface provides enumerator for // enumerating through the collection of com objects IEnumGUID *pEnumGUID = NULL; // We are interested in finding out only controls // so put CATID_Control in the array CATID pcatidImpl[1]; //CATID pcatidReqd[1]; pcatidImpl[0] = CATID_Control; // Now enumerate the classes i.e. com objects of this type. pCatInfo->EnumClassesOfCategories(1, pcatidImpl, ((ULONG)-1), NULL, &pEnumGUID); // 若cRequired为0,则仅列出没有“Required Categories”的类。只有将其设为-1,才是忽略“Required Categories”筛选。 // Enumerate as long as you get S_OK CLSID clsid; //控件的GUID while ((hr = pEnumGUID->Next(1, &clsid, NULL)) == S_OK) { BSTR bstrClassName; // Get the information of class // This is what MSDN says about the parameters /*----------------------------------------------- 1. USERCLASSTYPE_FULL The full type name of the class. 2. USERCLASSTYPE_SHORT A short name (maximum of 15 characters) that is used for popup menus and the Links dialog box. 3. USERCLASSTYPE_APPNAME The name of the application servicing the class and is used in the Result text in dialog boxes. -----------------------------------------------*/ OleRegGetUserType (clsid, USERCLASSTYPE_FULL, &bstrClassName); //CString strControlName(bstrClassName); //// Add string in our listbox //m_list.AddString(strControlName); // == main == CATID catid; IEnumCATID *pEnumCATID = NULL; fprint_GUID(stdout, clsid); _tprintf(_T("\t%ls"), bstrClassName); // 因BSTR变量指向UTF16编码的字符串. _tprintf(_T("\n")); // EnumImplCategoriesOfClass if (_show_catid) { _tprintf(_T("\tEnumImplCategoriesOfClass:\n")); if (S_OK == pCatInfo->EnumImplCategoriesOfClass(clsid, &pEnumCATID)) { while (S_OK == pEnumCATID->Next(1, &catid, NULL)) { _tprintf(_T("\t\t")); fprint_GUID(stdout, catid); PWCHAR pszDesc = NULL; pCatInfo->GetCategoryDesc(catid, lcid, &pszDesc); _tprintf(_T("\t%ls"), pszDesc); ::CoTaskMemFree(pszDesc); _tprintf(_T("\n")); } pEnumCATID->Release(); } } // EnumReqCategoriesOfClass if (_show_catid) { _tprintf(_T("\tEnumReqCategoriesOfClass:\n")); if (S_OK == pCatInfo->EnumReqCategoriesOfClass(clsid, &pEnumCATID)) { while (S_OK == pEnumCATID->Next(1, &catid, NULL)) { _tprintf(_T("\t\t")); fprint_GUID(stdout, catid); PWCHAR pszDesc = NULL; pCatInfo->GetCategoryDesc(catid, lcid, &pszDesc); _tprintf(_T("\t%ls"), pszDesc); ::CoTaskMemFree(pszDesc); _tprintf(_T("\n")); } pEnumCATID->Release(); } } } // we are done so now release the interface ptr pCatInfo->Release(); }
二、测试
在以下编译器中成功编译——
VC6:x86版。
VC2005:x86版。
2.1 仅列出ActiveX控件的CLSID与名称
如果直接运行,即没有命令行参数时,就仅列出ActiveX控件的CLSID与名称。
例如在命令提示符中输入“enumactivex”——
或者运行“enumactivex_ui.exe”——
2.2 还列出 implemented/required CATIDs
如果随便写上一个命令行参数,就还会列出 implemented/required CATIDs。
例如在命令提示符中输入“enumactivex”——
或者运行“enumactivex_ui.exe”,并在自定义文本框中随便输入一个参数——
参考文献——
《枚举系统的ActiveX控件并在视图中显示》. S0746. http://hi.baidu.com/dakzjbwlqctuyzr/item/46d199e81f81f312595dd86c
《[C#] cmdarg_ui:“简单参数命令行程序”的通用图形界面》. http://www.cnblogs.com/zyl910/archive/2012/06/19/cmdarg_ui.html