Click here to Skip to main content
15,886,026 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi Everyone,

After exploring the various ways, I have found “Windows Update Agent API” is the better way to collect windows update information from any Windows OS post Windows 2000 SP3.

I have created a win32 console application in C++ to collect the windows update info with below mentioned approach.

1.Initialize COM.
2.Get Handle to Windows Update Session.
3.Create an Update Searcher (Used IUpdateSearcher interface).
4.Perform search with the search criteria “IsInstalled=1 or IsHidden=1 or IsPresent=1”. Here I am getting the results of both type “Software” and “Driver”.
5.Iterate through results.
6.Cleanup memory allocated to objects and Uninitialize COM.

Following are the results I have observed while testing the console application with Administrator previleges:
1.In Windows XP 64 bit, WUA API is returning less results when compared to “WMIC QFE GET”
2.In Windows Vista, WUA API is not returning any results.
3.In Windows 7, 2008, WUA API is returning more results than WMIC QFE GET.

I have taken the approach of using WUA API when compared to querying the “Win32_QuickFixEngineering” class with WMI because the latter gives the update entries that are updated with Component Based Servicing.

Could you please answer the following queries:
1.Are there any errors in my approach to retrieve the update information?
2.Could you please point to some good articles/information about using WUA API?
3.Are there any specific settings that need to be taken care in programming based on OS flavour?
4.Is there any specific build process with respect to 32 bit and 64 bit machines separately?
5.Should “Windows Update” service be mandatory enabled to run the WUA API code?

I have copied the sample code I am using. This code is written to collect the KB Numbers of installed updates:

C++
#include <Windows.h>
#include <iostream>
#include <atlbase.h>
#include <Wuapi.h>
#include <wuerror.h>
#include <list>
#include <fstream>
#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"
#include <MsXml.h>

using namespace std;


int main()
{
try
{
    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;
    LONG totalKB=0;
    results->get_Updates(&updateList);
    updateList->get_Count(&updateSize);

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

	ofstream outputFile;
	outputFile.open("C:\\test.txt",ios::out);

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


		updateList->get_Item(i, &updateItem);
		updateItem->get_Title(&updateName);
		USES_CONVERSION;
		outputFile << W2A(CString(updateName)) << " --- ";
		updateItem->get_KBArticleIDs(&KBCollection);
		KBCollection->get_Count(&KBCount);
		for(int i=0;i<KBCount;i++)
		{
			BSTR KBValue;
			totalKB += 1;
			KBCollection->get_Item(i,&KBValue);
			USES_CONVERSION;
			outputFile <<  W2A(CString("KB")) << W2A(CString(KBValue)) << endl;
		}

        IUpdateCollection *updtCollection;
        LONG updtBundledCount;        
		
        //Retrieve the bundled updates
		outputFile << W2A(CString("\t 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;
                
                updtCollection->get_Item(j,&bundledUpdateItem);   
				
				bundledUpdateItem->get_Title(&updateName);
				USES_CONVERSION;
				outputFile <<  W2A(CString("\t")) << W2A(CString(updateName)) << " - ";
                
				updateItem->get_KBArticleIDs(&KBCollection);
				KBCollection->get_Count(&KBCount);
				for(int i=0;i<KBCount;i++)
				{
					BSTR KBValue;
					totalKB += 1;
					KBCollection->get_Item(i,&KBValue);
					outputFile <<  W2A(CString("KB")) << W2A(CString(KBValue)) << endl;
				}
                //wcout<<L"    "<<j+1<<" - "<<bundledName<<endl;
            }

        }
    }
	wcout << "Total KBs : " << totalKB << endl;
	outputFile.close();
    ::CoUninitialize();
	}
	catch( const std::exception & ex )
	{
		cout << ex.what();
		::CoUninitialize();
	}
    return 0;
}
Posted

1 solution

Hi,

The below URL may be helpful.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa386907(v=vs.85).aspx[^]

# I have also created a softwaret that shows and exports the history of Windows Update,
and think that WUA API is not sufficient.
So, I use the combination WUA, WMI, and WSH.
Using WSH mainly, WUA and WMI supplementary.

# sorry for my poor English.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900