鸿 网 互 联 www.68idc.cn

[VC] 枚举ActiveX控件的 CLSID 和 implemented/required CATIDs

来源:互联网 作者:佚名 时间:2012-10-13 10:24
一、代码 全部代码 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.hvoid doenumactivex(void);int _show_catid = FALSE;// 获取程序位数(被编译为

一、代码

  全部代码——

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”,并在自定义文本框中随便输入一个参数——

 
网友评论
<