c++windowsvbscriptwuapi

unexplained differences in wuapi between VBScript and C++


When trying to use wuapi to query Windows 7 Enterprise SP1 for updates, the attached VBScript sample returns different results than the attached C++ sample. The VBScript includes updates for Microsoft Office, which is what I want. During my research I discovered IUpdateSearcher3 interface that exposes SearchScope, which appears to be what I need to use. However, I am having difficulty creating the interface. The question that I have is, why are the results different for the two versions, and how can I make the C++ version include Office checks to align with the VBScript version?

Attaching the sample code and output. Notice the C++ version does not include the Office updates from the VBScript output:

50> Security Update for Microsoft Outlook 2010 (KB3115474) 32-Bit Edition
51> Security Update for Microsoft Office 2010 (KB3114400) 32-Bit Edition
52> Security Update for Microsoft Office 2010 (KB3114869) 32-Bit Edition
57> Security Update for Microsoft Word 2010 (KB3115471) 32-Bit Edition
58> Update for Microsoft Excel 2010 (KB3115476) 32-Bit Edition
59> Definition Update for Microsoft Office 2010 (KB3115475) 32-Bit Edition

VBScript Sample:

Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
WScript.Echo "List of applicable items on the machine:"

For I=0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

VBScript Output: Searching for updates...

List of applicatble items on the machine:
1> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2656356)
2> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2604115)
3> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2729452)
4> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2742599)
5> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2789645)
6> Update for Windows 7 (KB2798162)
7> Security Update for Windows 7 (KB2813430)
8> Update for Windows 7 (KB2868116)
9> Security Update for Windows 7 (KB2868626)
10> Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2836943)
11> Security Update for Windows 7 (KB2871997)
12> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2931356)
13> Security Update for Windows 7 (KB2973351)
14> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2937610)
15> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2943357)
16> Security Update for Windows 7 (KB2758857)
17> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2972211)
18> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2973112)
19> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2894844)
20> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2972100)
21> Security Update for Windows 7 (KB2984972)
22> Security Update for Windows 7 (KB2992611)
23> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2978120)
24> Security Update for Windows 7 (KB3003743)
25> Security Update for Windows 7 (KB3011780)
26> Security Update for Windows 7 (KB3004375)
27> Security Update for Windows 7 (KB3033929)
28> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3037574)
29> Security Update for Windows 7 (KB3061518)
30> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3023215)
31> Security Update for Windows 7 (KB3031432)
32> Security Update for Windows 7 (KB3072630)
33> Security Update for Windows 7 (KB3060716)
34> Security Update for Windows 7 (KB3071756)
35> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3074543)
36> Security Update for Windows 7 (KB3042058)
37> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3097989)
38> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3122648)
39> Security Update for Windows 7 (KB3126587)
40> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3127220)
41> Update for Windows 7 (KB3138612)
42> Security Update for Windows 7 (KB3146706)
43> Security Update for Windows 7 (KB3149090)
44> Security Update for Windows 7 (KB3153171)
45> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3142024)
46> Security Update for Windows 7 (KB3161561)
47> Security Update for Windows 7 (KB3159398)
48> Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3163245)
49> Security Update for Microsoft OneNote 2010 (KB3114885) 32-Bit Edition
50> Security Update for Microsoft Outlook 2010 (KB3115474) 32-Bit Edition
51> Security Update for Microsoft Office 2010 (KB3114400) 32-Bit Edition
52> Security Update for Microsoft Office 2010 (KB3114869) 32-Bit Edition
53> Security Update for Windows 7 (KB3167679)
54> Security Update for Windows 7 (KB3177725)
55> Security Update for Windows 7 (KB3178034)
56> Cumulative Security Update for Internet Explorer 11 for Windows 7 (KB3175443)
57> Security Update for Microsoft Word 2010 (KB3115471) 32-Bit Edition
58> Update for Microsoft Excel 2010 (KB3115476) 32-Bit Edition
59> Definition Update for Microsoft Office 2010 (KB3115475) 32-Bit Edition
60> Update for Windows 7 (KB3177723)

C++ Sample:

#include "stdafx.h"
#include <Windows.h>
#include <wuapi.h>


int _tmain(int argc, _TCHAR* argv[])
{
    IUpdateSearcher* updateSearcher = NULL;
    IUpdateSession* updateSession = NULL;
    IUpdateCollection* updateList = NULL;
    ISearchResult* results = NULL;
    IUpdate* updateItem = NULL;
    BSTR criteria = NULL;
    LONG updateSize = 0;
    HRESULT hr;

    if((hr = CoInitialize(NULL)) != S_OK) {
        exit(-1);
    }
    if((hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER,
                    IID_IUpdateSession, (LPVOID*)&updateSession)) != S_OK) {
        exit(-1);
    }
    if((hr = updateSession->CreateUpdateSearcher(&updateSearcher)) != S_OK) {
        exit(-1);
    }
    if((hr = updateSearcher->put_ServerSelection(ssWindowsUpdate)) != S_OK) {
        exit(-1);
    }
    criteria = SysAllocString(L"IsInstalled=0 and Type='Software' and IsHidden=0");
    hr = updateSearcher->Search(criteria, &results);
    if ((hr = updateSearcher->Search(criteria, &results)) == S_OK) {
        OutputDebugString(L"[*]Successfully completed search for updates on this host");
    } else {
        OutputDebugString(L"[-]Failed to search for updates");
    }
    SysFreeString(criteria);
    results->get_Updates(&updateList);
    updateList->get_Count(&updateSize);
    if(updateSize == 0) {
        OutputDebugString(L"[-]No updates available for this host");
        CoUninitialize();
        exit(0);
    }
    for(LONG i = 0; i < updateSize; i++) {
        BSTR updateName;
        updateList->get_Item(i, &updateItem);
        updateItem->get_Title(&updateName);
        OutputDebugString(updateName);
    }
    CoUninitialize();
    exit(0);
}

C++ Output:

[*]Successfully completed search for updates on this host
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2656356)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2604115)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2729452)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2742599)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2789645)
Update for Windows 7 (KB2798162)
Security Update for Windows 7 (KB2813430)
Update for Windows 7 (KB2868116)
Security Update for Windows 7 (KB2868626)
Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2836943)
Security Update for Windows 7 (KB2871997)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2931356)
Security Update for Windows 7 (KB2973351)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2937610)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2943357)
Security Update for Windows 7 (KB2758857)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2972211)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2973112)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2894844)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2972100)
Security Update for Windows 7 (KB2984972)
Security Update for Windows 7 (KB2992611)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB2978120)
Security Update for Windows 7 (KB3003743)
Security Update for Windows 7 (KB3011780)
Security Update for Windows 7 (KB3004375)
Security Update for Windows 7 (KB3033929)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3037574)
Security Update for Windows 7 (KB3061518)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3023215)
Security Update for Windows 7 (KB3031432)
Security Update for Windows 7 (KB3072630)
Security Update for Windows 7 (KB3060716)
Security Update for Windows 7 (KB3071756)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3074543)
Security Update for Windows 7 (KB3042058)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 x86 (KB3097989)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3122648)
Security Update for Windows 7 (KB3126587)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3127220)
Update for Windows 7 (KB3138612)
Security Update for Windows 7 (KB3146706)
Security Update for Windows 7 (KB3149090)
Security Update for Windows 7 (KB3153171)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3142024)
Security Update for Windows 7 (KB3161561)
Security Update for Windows 7 (KB3159398)
Security Update for Microsoft .NET Framework 3.5.1 on Windows 7 SP1 (KB3163245)
Security Update for Windows 7 (KB3167679)
Security Update for Windows 7 (KB3177725)
Security Update for Windows 7 (KB3178034)
Cumulative Security Update for Internet Explorer 11 for Windows 7 (KB3175443)
Update for Windows 7 (KB3177723)

Solution

  • This is your problem:

    if((hr = updateSearcher->put_ServerSelection(ssWindowsUpdate)) != S_OK) {
        exit(-1);
    }
    

    That directs WUAPI to use Windows Update explicitly, which includes only updates for Windows itself, not for other Microsoft software. The VBScript code doesn't do this, so it uses whichever service is configured to be the default. On your machine, that would appear to be Microsoft Update.

    I've tried your code on a test machine (also configured to default to Microsoft Update) and confirmed that removing the call to put_ServerSelection() resolved the problem. It doesn't seem to make any difference whether the code is running as 32-bit or 64-bit.

    If you want to explicitly search Microsoft Update regardless of how the machine is configured, you can do so by explicitly specifying the Service ID. In an enterprise environment, this will also ensure that the client searches Microsoft Update directly rather than the local WSUS server:

    if((hr = updateSearcher->put_ServerSelection(ssOthers)) != S_OK) {
        exit(-1);
    }
    
    BSTR serviceID = SysAllocString(L"7971f918-a847-4430-9279-4a52d1efe18d");
    
    if ((hr = updateSearcher->put_ServiceID(serviceID)) != S_OK)
    {
        exit(-1);
    }
    
    SysFreeString(serviceID);
    

    The GUID shown above for Microsoft Update can be found in the example code in the MSDN article titled Opt-In to Microsoft Update.

    (It is not always necessary to first opt in to Microsoft Update in order to perform a Microsoft Update scan using the API. In my testing, Windows 7 machines did not require an opt-in but Windows 10 machines did. This may vary depending on circumstances.)