Exploring Windows APIs: WUA
Introduction

Windows XP SP2 made available a new API for managing the Windows Update Service. As with many a new API this one is COM-callable and therefore can be used from Visual Objects applications. In this article I would like to present an example to get you started. The API however is reasonably complex and powerful and there’s much more to explore. You might want to have a good look at the reference documentation in detail on MSDN to see what else is on the menu and to your liking. The sample presented here searches updates, presents them in a modern XP-style UI and allows the user to select and install updates selectively. It will also show you how to check for installed updates and install them programmatically when you need that.
It is where the system takes you when you hit that Windows Update menu option

Windows Update Service
Before we dive into the VO-code first a little about the Windows Update Service. This is actually a website and service available to all Windows users. You’ve probably seen it. It is where the system takes you when you hit that Windows Update menu option. At this moment (May 2005) it is still all Windows, and there is a different procedure for Office for example, but this will soon change. There are also different versions of the Update service itself. I have tested the Interface using version 6 (beta). The interesting thing about all of this though is that in the near future we will be able to have a service like this running on our own internal servers (WSUS) and it will be available for other products as well. Microsoft plans on releasing the next version as “Microsoft” update service (so not Windows anymore) which will also support Office, SQL Server and Exchange initially, but should open up to all current products and third parties. So Microsoft is pushing this technology hard and at the time of writing (again May 2005), there even is a new version (in beta) of the update service and a .Net version of the Client API. When looking at the published documentation for this, I found notices that the documentation is still Microsoft confidential. However it is actually publicly available on www.microsoft.com as of April 2005. All in all more than enough reasons I think to seriously have a look at this technology.
To begin with for those of you that like to dive right in and get your hands dirty I have included a demo application written in Visual Objects 2.7b-1 which demonstrates how to query the service for updates, allows you to select a specific update and install it for you.
Below is a picture of the main dialog window of this application listing a few updates ready for installation.

It also shows how to apply Listview grouping and a background image as provided by Windows XP styles.
Generate Base Classes
Visiting the Windows Update Website for the first time installs the Client, a DLL called WUAPI.DLL which you will find in your System32-directory. You can use this or WUAENG.DLL (the engine) to find out what version you have installed. It should be 5.4.3790.1000 or greater. From VO all you need to do is generate Automation Wrapper classes using Tools, Automation server to be able to start using the object model ... well, euh ... that and study the documentation which you will find on MSDN. Although a lot of the samples are in Windows-script, they are pretty good and fairly easy to translate into VO code.

First of all we can inspect or change the user specific settings. We’ll do that the easy way by popping up the UI Windows XP now has for that. The code for that is very straight forward: just instantiate the IAutomaticUpdates-object and call the ShowSettingsDialog-method. As you can see, I prefixed my generated class with WUA_ to easily differentiate them from others I might use. Actually I’m pretty happy with the work the VO development team did on the Automation server code generation tool. They have gotten rid of many annoying ‘features’. If you haven’t seen or used it for a while, it is worth having another look. Here’s the code I needed for showing that dialog.
METHOD ShowSettings( ) CLASS MainDialog
LOCAL oUSettings AS WUA_IAutomaticUpdates
oUSettings := WUA_IAutomaticUpdates{}
oUSettings:ShowSettingsDialog()
RETURN SELF
You can now tell your users to switch it off completely and build them a nice application that handles the process for them in Visual Objects.
So we are now ready for the more serious stuff
So we are now ready for the more serious stuff, starting with querying the update information from the server. For this we need the IUpdateSession-object or “interface” if you prefer. We use that to create an IUpdateSearcher-object that has a search method which accepts a query string. The query string will be used to specify what kind of updates you would like to see.
I must admit the documentation on the syntax to use is a bit complex, but with a bit of exploring samples and testing I had the basic thing working quickly. It’s clear that things can be added to this by Microsoft fairly easily and they probably intend to, judging by the remarks in the very fresh documentation.
The string "IsInstalled=0 and Type='Software'" gives you all not installed software updates that are available. Obviously, when you leave out IsInstalled you will also get already installed updates allowing you to have a look at the update history.
The results are passed back to you using an ISearchResult-object which, if it was successful, has a collection of IUpdate-Items. So, simplified, you could end up with something like this to build a listview of IUpdate items:
METHOD GetUpdateInfo( ) CLASS MainDialog
LOCAL updateSearcher AS WUA_IUpdateSearcher
LOCAL searchResult AS WUA_ISearchResult
LOCAL update AS WUA_IUpdate
LOCAL I AS DWORD
SELF:Pointer := Pointer{POINTERHOURGLASS}
SELF:updateSession := WUA_IUpdateSession{}
// Issue a search
updateSearcher := updateSession:CreateupdateSearcher()
searchResult := updateSearcher:Search("IsInstalled=0")
//and Type='Software'")
SELF:oDClvUpdates:DeleteAll()
FOR I = 0 TO searchResult:Updates:Count-1
update := searchResult:Updates:[Item,I]
SELF:oDClvUpdates:AddItem(update)
NEXT
SELF:Pointer := Pointer{POINTERARROW}
SELF:oDClvUpdates:SetFocus()
RETURN SELF
You can query the Resultcode-property of ISearchResult for <> S_OK and query the Warnings-collection for info on what’s happening.
The UpdateItems contain all kinds of properties to display details about them. I am using the Description-property for display purposes (in the ListviewItemChanged method) and IsBeta and Maxdownloadsize as column information. I use the Downloadpriority to set grouping options for the Listview.
Download Updates
After we have a list of candidates for installation, we need to download them. For this there is an IUpdateDownloader-interface which can not be instantiated but is created for you by calling the Session’s CreateUpdateDownloader method which is why in the previous code the Session-object was put in an IVar of the dialog instead of a local. You tell the Downloader which updates you need by providing a collection of Updateitems which in turn are created by calling Add on this collection using the names of the updates.
Calling the Download method on the UpdateDownloader returns a DownloadResult-object that can be interrogated to find out if the download was successful or a reason of failure when something went wrong. The same routine will be needed for actual installation, using an UpdateInstaller-class.
The code in the sample is synchronous, but the object model also provides asynchronous methods, so you could do the downloading and installing in the background. Below is the code I used to download and install.
METHOD InstallSelectedUpdate( ) CLASS MainDialog
LOCAL oTb AS TextBox
LOCAL cInfo AS STRING
LOCAL updateToInstall AS WUA_IUpdateCollection
LOCAL downloader AS WUA_IUpdateDownloader
LOCAL downloadResult AS WUA_IDownloadResult
LOCAL installer AS WUA_IUpdateInstaller
LOCAL installationResult AS WUA_IInstallationResult
LOCAL oListViewItem AS ListviewItem
updateToInstall:=WUA_IUpdateCollection{}
oListViewItem := SELF:oDClvUpdates:GetSelectedItem()
IF oListViewItem # NULL_OBJECT
SELF:oCCInstallSelectedUpdate:Disable()
updateToInstall:Add( oListviewItem:GetValue(#Title))
cInfo := oListviewItem:GetText(#Title)
oTb := TextBox{SELF,"Confirm",;
"Would you like to download and install "+;
cInfo+" now? ",BUTTONOKAYCANCEL+BOXICONQUESTIONMARK}
IF oTb:Show() == BOXREPLYOKAY
downloader := updateSession:CreateUpdateDownloader()
downloader:Updates := updateToInstall
SELF:oCCShowSettings:Disable()
SELF:oCCGetUpdateInfo:Disable()
SELF:oDClvUpdates:Disable()
SELF:Pointer := Pointer{POINTERHOURGLASS}
SELF:oDCDescription:Textvalue := ;
"Downloading..."+CRLF
DoEvents()
downloadResult := downloader:Download()
SELF:oDCDescription:Textvalue += ;
"Download Result: " +;
ResultString(downloadResult:ResultCode) + CRLF
SELF:oDCDescription:Textvalue += ;
"Installing update..." + CRLF
DoEvents()
installer := updateSession:CreateUpdateInstaller()
installer:Updates := updateToInstall
installationResult := installer:Install()
SELF:oDCDescription:Textvalue += ;
"Installation Result: " +;
ResultString(installationResult:ResultCode) + CRLF
DoEvents()
IF installationResult:RebootRequired
Infobox{SELF,"Attention",;
"You Should re-boot now. (not automatic ;-))"}:;
Show()
ENDIF
ENDIF
ENDIF
SELF:Pointer := Pointer{POINTERARROW}
SELF:oCCInstallSelectedUpdate:Enable()
SELF:oCCShowSettings:Enable()
SELF:oCCGetUpdateInfo:Enable()
SELF:oDClvUpdates:Enable()
RETURN SELF
This covers the basics you need to know to get started. Additionally I have created a sample that allows you to research the various Search expressions and one that that displays all properties of the Update items.
Search Tester
WUASearchDialog.AEF is a sample application that allows us to experiment with different values as a parameter for the Updatesearcher-searchmethod. The SDK helpfile (WUA_SDK.CHM) has got a good table explaining the different options. You can download the helpfile as a .CHM or look it up on MSDN.
Update Inspector
Double clicking on an update-item in the WUASearchDialog-app opens a detail-dialog showing many available properties of the Update-items, demonstrating how to inspect an update-item. I am sure you can think of interesting things to do with these Update-items yourself.
Conclusion
We have only scratched the surface of what this API is capable of and what Microsoft intends to offer in the future. In particular, in situations where you need more control over when and how updates are installed or when Microsoft decides to open this up for third parties (us) this API will be of great value. It is also a very interesting way to explore OLE-client application development in Visual Objects using the well designed objectmodel WUA offers.
Interesting links:
Links to the SDK’s:
Windows Update Agent API, what Microsoft says:
Purpose
The Windows® Update Agent (WUA) API is a set of COM interfaces that enable programmers to access Windows Update. Scripts or programs can be written to examine which updates are currently available for a computer, and install or uninstall updates.
This documentation describes a preliminary version of the WUA API available with Windows XP SP2. Note that this preliminary version of the WUA API can be used to scan for updates on the local computer only. The capability to remotely scan the updates needed by other computers on a network, for example by using DCOM, has been disabled in this preliminary version.
Where Applicable
System administrators can use WUA to programmatically determine which updates should be applied to a computer, download those updates, and install them with little or no user intervention.
Independent software vendors (ISV) and end-user developers can integrate WUA features into computer management or patch management software to provide a seamless operating environment.
Developer Audience
You can write WUA applications in several languages. WUA defines interfaces and objects that are accessible from Visual Basic, Visual Basic Scripting Edition (VBScript), JScript, and from C and C++. A familiarity with COM programming is useful to the WUA programmer.
Run-Time Requirements
WUA requires Windows XP or Windows 2000 Professional SP3. It also assumes the Windows Update Agent is installed on the client computer. This is done automatically when you visit the Update Website the first time (http://v5.windowsupdate.microsoft.com/v5consumer/default.aspx?ln=en-us).