zoukankan      html  css  js  c++  java
  • [VC] 枚举ActiveX控件的 CLSID 和 implemented/required CATIDs 的小工具

    作者: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


    源码下载——
    https://files.cnblogs.com/zyl910/enumactivex.rar

    作者:zyl910
    版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0.
  • 相关阅读:
    芯片手冊写错了,非常悲剧
    编程之美读书笔记1.8
    贪心算法
    codeforces Looksery Cup 2015 D. Haar Features
    NS3网络仿真(5): 数据包分析
    hdu1116 Play on Words--并查集
    程序猿生存定律-六个程序猿的故事(2)
    保存Activity的状态
    9月份入读哈工大计算机研究生了
    leetcode第一刷_Same Tree
  • 原文地址:https://www.cnblogs.com/zyl910/p/enumactivex.html
Copyright © 2011-2022 走看看