Question

When we try to retrieve the Windows Update Information with WUA API, the following is the process I have followed. But I am bit confused with IUpdate::BundledUpdates property.

  1. Create an IUpdateSearcher
  2. Search based on a search criteria. I provided search criteria as "IsHidden=1 or IsInstalled=1"
  3. You will have a IUpdateCollection as result of search.
  4. Using get_Item in IUpdateCollection, I retrieved each update (IUpdate) and printed the required values (KB numbers in my case).
  5. But again in IUpdate, you have a BundledUpdate property that gives IUpdateCollection with get_BundledUpdates() method. When I iterated over the results of BundledUpdates, I have got no results.

Am I missing something in retrieving bundled updates? (OR) does the criteria I specified includes Bundled Updates as part of first result set of IUpdateCollection?

Also in MSDN, examples are lacking for each interface in WUA API, Could someone provide any resources that explains clearly what each interface in WUA API does?

Added full source code of C++ console Application:

#include <wuapi.h>
#include <iostream>
#include <wuerror.h>

using namespace std;


int main()
{

    HRESULT hr;
    hr = CoInitialize(NULL);

    IUpdateSession* iUpdate;
    IUpdateSearcher* searcher;
    ISearchResult* results;
    BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1 or IsPresent=1");

    hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER,
        IID_IUpdateSession, (LPVOID*)&iUpdate);
    hr = iUpdate->CreateUpdateSearcher(&searcher);

    wcout << L"Searching for updates ..."<<endl;
    hr = searcher->Search(criteria, &results);
    SysFreeString(criteria);

    switch(hr)
    {
    case S_OK:
        wcout<<L"List of applicable items on the machine:"<<endl;
        break;
    case WU_E_LEGACYSERVER:
        wcout<<L"No server selection enabled"<<endl;
        return 0;
    case WU_E_INVALID_CRITERIA:
        wcout<<L"Invalid search criteria"<<endl;
        return 0;
    }

    IUpdateCollection * updateList;
    IUpdate *updateItem;
    LONG updateSize;
    BSTR updateName;

    results->get_Updates(&updateList);
    updateList->get_Count(&updateSize);

    if (updateSize == 0)
    {
        wcout << L"No updates found"<<endl;
    }

    for (LONG i = 0; i < updateSize; i++)
    {
        IStringCollection *KBCollection;
        LONG KBCount;
        updateList->get_Item(i, &updateItem);
        updateItem->get_KBArticleIDs(&KBCollection);
        KBCollection->get_Count(&KBCount);
        for(int k=0;k<KBCount;k++)
        {
            BSTR KBValue;
            KBCollection->get_Item(k,&KBValue);
            wcout << L"KB" << KBValue << endl;
        }

        //Retrieve the bundled updates
        IUpdateCollection *updtCollection;
        updateItem->get_BundledUpdates(&updtCollection);
        LONG updtBundledCount;
        updtCollection->get_Count(&updtBundledCount);
        for(LONG j=0;j<updtBundledCount;j++)
        {
            cout<<"Bundled KBs" <<endl;
            IUpdate *bundledUpdateItem;
            updtCollection->get_Item(j,&bundledUpdateItem);
            bundledUpdateItem->get_KBArticleIDs(&KBID);
            if(KBID != NULL)
            {
                LONG KBCount;
                BSTR KBIDValue;

                KBID->get_Count(&KBCount);
                for(LONG j=0;j<KBCount;j++)
                {

                    wcout << "KB" <<(KBIDValue) << endl;
                    temp.setKBID(KBIDValue);
                }
            }
        }
    }

    wcout << L"Total KB Count : " << updateSize << endl;
    CoUninitialize();

    return 0;
}
Was it helpful?

Solution

I just fix your code in order to retrieve the Bundled Updates.

#include "stdafx.h"
#include <wuapi.h>
#include <iostream>
#include <wuerror.h>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr;
    hr = CoInitialize(NULL);

    IUpdateSession* iUpdate;
    IUpdateSearcher* searcher;
    ISearchResult* results;
    BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1 or IsPresent=1");

    hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&iUpdate);
    hr = iUpdate->CreateUpdateSearcher(&searcher);

    wcout << L"Searching for updates ..."<<endl;
    hr = searcher->Search(criteria, &results); 
    SysFreeString(criteria);

    switch(hr)
    {
    case S_OK:
        wcout<<L"List of applicable items on the machine:"<<endl;
        break;
    case WU_E_LEGACYSERVER:
        wcout<<L"No server selection enabled"<<endl;
        return 0;
    case WU_E_INVALID_CRITERIA:
        wcout<<L"Invalid search criteria"<<endl;
        return 0;
    }

    IUpdateCollection *updateList;
    IUpdate *updateItem;
    LONG updateSize;
    BSTR updateName;

    results->get_Updates(&updateList);
    updateList->get_Count(&updateSize);

    if (updateSize == 0)
    {
        wcout << L"No updates found"<<endl;
    }

    for (LONG i = 0; i < updateSize; i++)
    {
        IStringCollection *KBCollection;
        LONG KBCount;
        updateList->get_Item(i,&updateItem);
        updateItem->get_Title(&updateName);
        wcout<<i+1<<" - "<<updateName<<endl;

        IUpdateCollection *updtCollection;
        LONG updtBundledCount;        
        //Retrieve the bundled updates
        updateItem->get_BundledUpdates(&updtCollection);
        hr = updtCollection->get_Count(&updtBundledCount);
        if ((updtBundledCount>0) && (hr ==S_OK))
        {
            wcout << L"Bundled Updates " <<(updtBundledCount) << endl;
            for(LONG j=0;j<updtBundledCount;j++)
            {
                IUpdate *bundledUpdateItem;
                BSTR bundledName;
                updtCollection->get_Item(j,&bundledUpdateItem);   
                bundledUpdateItem->get_Title(&bundledName);
                wcout<<L"    "<<j+1<<" - "<<bundledName<<endl;
            }
        }
    }
    ::CoUninitialize();
    wcin.get();
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top