Windows Update Agent API in C++

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#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;
}



Could someone please reply?
Topic archived. No new replies allowed.