By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
463,190 Members | 626 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 463,190 IT Pros & Developers. It's quick & easy.

Unable to retrieve all data with Windows Update Agent in C++

P: 1
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:

Expand|Select|Wrap|Line Numbers
  1. #include <Windows.h>
  2. #include <iostream>
  3. #include <atlbase.h>
  4. #include <Wuapi.h>
  5. #include <wuerror.h>
  6. #include <list>
  7. #include <fstream>
  8. #include "atlbase.h"
  9. #include "atlstr.h"
  10. #include "comutil.h"
  11. #include <MsXml.h>
  12.  
  13. using namespace std;
  14.  
  15.  
  16. int main()
  17. {
  18.     try
  19.     {
  20.     HRESULT hr;
  21.     hr = CoInitialize(NULL);
  22.  
  23.     IUpdateSession* iUpdate;
  24.     IUpdateSearcher* searcher;
  25.     ISearchResult* results;
  26.     BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1 or IsPresent=1");
  27.  
  28.     hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&iUpdate);
  29.     hr = iUpdate->CreateUpdateSearcher(&searcher);
  30.  
  31.     wcout << L"Searching for updates ..."<<endl;
  32.     hr = searcher->Search(criteria, &results); 
  33.     SysFreeString(criteria);
  34.  
  35.     switch(hr)
  36.     {
  37.     case S_OK:
  38.         wcout<<L"List of applicable items on the machine:"<<endl;
  39.         break;
  40.     case WU_E_LEGACYSERVER:
  41.         wcout<<L"No server selection enabled"<<endl;
  42.         return 0;
  43.     case WU_E_INVALID_CRITERIA:
  44.         wcout<<L"Invalid search criteria"<<endl;
  45.         return 0;
  46.     }
  47.  
  48.     IUpdateCollection *updateList;
  49.     IUpdate *updateItem;
  50.     LONG updateSize;
  51.     LONG totalKB=0;
  52.     results->get_Updates(&updateList);
  53.     updateList->get_Count(&updateSize);
  54.  
  55.     if (updateSize == 0)
  56.     {
  57.         wcout << L"No updates found"<<endl;
  58.     }
  59.  
  60.     ofstream outputFile;
  61.     outputFile.open("C:\\test.txt",ios::out);
  62.  
  63.     for (LONG i = 0; i < updateSize; i++)
  64.     {
  65.         IStringCollection *KBCollection;
  66.         BSTR updateName;
  67.         LONG KBCount;
  68.         updateList->get_Item(i,&updateItem);
  69.  
  70.  
  71.         updateList->get_Item(i, &updateItem);
  72.         updateItem->get_Title(&updateName);
  73.         USES_CONVERSION;
  74.         outputFile << W2A(CString(updateName)) << " --- ";
  75.         updateItem->get_KBArticleIDs(&KBCollection);
  76.         KBCollection->get_Count(&KBCount);
  77.         for(int i=0;i<KBCount;i++)
  78.         {
  79.             BSTR KBValue;
  80.             totalKB += 1;
  81.             KBCollection->get_Item(i,&KBValue);
  82.             USES_CONVERSION;
  83.             outputFile <<  W2A(CString("KB")) << W2A(CString(KBValue)) << endl;
  84.         }
  85.  
  86.         IUpdateCollection *updtCollection;
  87.         LONG updtBundledCount;        
  88.  
  89.         //Retrieve the bundled updates
  90.         outputFile << W2A(CString("\t Bundled Updates : "));
  91.         updateItem->get_BundledUpdates(&updtCollection);
  92.         hr = updtCollection->get_Count(&updtBundledCount);
  93.         if ((updtBundledCount>0) && (hr ==S_OK))
  94.         {
  95.             //wcout << L"Bundled Updates " <<(updtBundledCount) << endl;
  96.             for(LONG j=0;j<updtBundledCount;j++)
  97.             {
  98.                 IUpdate *bundledUpdateItem;
  99.  
  100.                 updtCollection->get_Item(j,&bundledUpdateItem);   
  101.  
  102.                 bundledUpdateItem->get_Title(&updateName);
  103.                 USES_CONVERSION;
  104.                 outputFile <<  W2A(CString("\t")) << W2A(CString(updateName)) << " - ";
  105.  
  106.                 updateItem->get_KBArticleIDs(&KBCollection);
  107.                 KBCollection->get_Count(&KBCount);
  108.                 for(int i=0;i<KBCount;i++)
  109.                 {
  110.                     BSTR KBValue;
  111.                     totalKB += 1;
  112.                     KBCollection->get_Item(i,&KBValue);
  113.                     outputFile <<  W2A(CString("KB")) << W2A(CString(KBValue)) << endl;
  114.                 }
  115.                 //wcout<<L"    "<<j+1<<" - "<<bundledName<<endl;
  116.             }
  117.  
  118.         }
  119.     }
  120.     wcout << "Total KBs : " << totalKB << endl;
  121.     outputFile.close();
  122.     ::CoUninitialize();
  123.     }
  124.     catch( const std::exception & ex )
  125.     {
  126.         cout << ex.what();
  127.         ::CoUninitialize();
  128.     }
  129.     return 0;
  130. }
Oct 18 '12 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.