Some of the cumulative & feature updates not giving download url (windows 10).


Joined
Nov 25, 2019
Messages
5
Reaction score
0
I got this code from following link

https://gist.github.com/apsun/b471c2e11dab94ad690d

where i added this code

res = update->get_BundledUpdates(&updatecol);
//res = updatecol->get_Count(&j);
res = updatecol->get_Item(0,&updateTmp);
res = update->get_KBArticleIDs(&updateKBIDs);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID list", res);
goto innerCleanup;
}
res = updateTmp->get_DownloadContents(&pDownUrl);
if(SUCCEEDED(res))
{
BSTR url;
res = pDownUrl->get_Count(&count);
res = pDownUrl->get_Item(0, &downloadContent);
if(FAILED(res))
{
HandleError(L"Failed to get url article ID count", res);
//goto innerCleanup;
}
else
{
res = downloadContent->get_DownloadUrl(&url);
if(FAILED(res))
{
//goto innerCleanup;
}
else
{
std::wcout << L"URL" << L':' << url < <endl;

This above code working fine till windows 8.1
but in some of the cumulative updates & feature updates, not getting download url in windows 10.
 
Last edited:
Ad

Advertisements

Regedit32

Moderator
Joined
Mar 4, 2016
Messages
3,620
Reaction score
1,130
For clarity,

When you got this code from GitHub. Which code? The one that opens in the URL you posted, or one of the three revisions the Author of the code later posted?

Also, when you added your additional code; where precisely did you add it.

It'd be easier to analyse the issue if we could see the completed code you are using.

On a side note, I'm trying to remember when Microsoft came through on their promise to remove ActiveX control from their Catalog site, which meant you could easily access the download links from any browser, but it also meant a number of changes were made on the Catalog, and I'm wondering, whether this indirectly is part of your problem with you now very dated Code example from GitHub.
 
Joined
Nov 25, 2019
Messages
5
Reaction score
0
Hi,

I used this code 1 week ago.
For detecting updates, MSDN provides these APIs.
Please check this code, including my changes,


#include <SDKDDKVer.h>
#include <Windows.h>
#include <comdef.h>
#include <wuapi.h>

#include <string>
#include <iostream>

void HandleError(LPCWSTR message, HRESULT result)
{
_com_error error(result);
LPCTSTR errorText = error.ErrorMessage();
std::wcerr << message << L": " << errorText << std::endl;
}

int main()
{
IUpdateSession *updateSession = NULL;
IUpdateSearcher *updateSearcher = NULL;
ISearchResult *searchResult = NULL;
IUpdateCollection *updates = NULL;
IUpdateDownloadContentCollection *pDownUrl = NULL;
IUpdateDownloadContent *downloadContent = NULL;
HRESULT res;
int ret = 1;
LONG count;
MessageBox(NULL, L"windows", L"updates", MB_OK);
res = CoInitializeEx(NULL, 0);
if (FAILED(res)) {
HandleError(L"Failed to initialize COM", res);
return 1;
}

res = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID *)&updateSession);
if (FAILED(res)) {
HandleError(L"Failed to create update session", res);
goto cleanup;
}

res = updateSession->CreateUpdateSearcher(&updateSearcher);
if (FAILED(res)) {
HandleError(L"Failed to create update searcher", res);
goto cleanup;
}

res = updateSearcher->put_IncludePotentiallySupersededUpdates(VARIANT_TRUE);
if (FAILED(res)) {
HandleError(L"Failed to set search options", res);
goto cleanup;
}

BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1");
res = updateSearcher->Search(criteria, &searchResult);
SysFreeString(criteria);
if (FAILED(res)) {
HandleError(L"Failed to search for updates", res);
goto cleanup;
}

res = searchResult->get_Updates(&updates);
if (FAILED(res)) {
HandleError(L"Failed to retrieve update list from search result", res);
goto cleanup;
}

LONG updateCount;
res = updates->get_Count(&updateCount);
if (FAILED(res)) {
HandleError(L"Failed to get update count", res);
goto cleanup;
}

for (LONG i = 0L; i < updateCount; ++i)
{
IUpdate *update = NULL;
IUpdate *updateTmp = NULL;
IUpdateCollection *updatecol = NULL;
IStringCollection *updateKBIDs = NULL;
bool innerError = true;
res = updates->get_Item(i, &update);
if (FAILED(res)) {
HandleError(L"Failed to get update item", res);
goto innerCleanup;
}
res = update->get_BundledUpdates(&updatecol);
//res = updatecol->get_Count(&j);
res = updatecol->get_Item(0,&updateTmp);
res = update->get_KBArticleIDs(&updateKBIDs);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID list", res);
goto innerCleanup;
}
res = updateTmp->get_DownloadContents(&pDownUrl);
if(SUCCEEDED(res))
{
BSTR url;
res = pDownUrl->get_Count(&count);
res = pDownUrl->get_Item(0, &downloadContent);
if(FAILED(res))
{
HandleError(L"Failed to get url article ID count", res);
//goto innerCleanup;
}
else
{
res = downloadContent->get_DownloadUrl(&url);
if(FAILED(res))
{
//goto innerCleanup;
}
else
{
std::wcout << L"URL" << L':' << url <<std::endl;
SysFreeString(url);
}
}
}

LONG kbIDCount;
res = updateKBIDs->get_Count(&kbIDCount);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID count", res);
goto innerCleanup;
}

for (LONG j = 0L; j < kbIDCount; ++j) {
BSTR kbID;
res = updateKBIDs->get_Item(j, &kbID);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID", res);
goto innerCleanup;
}
std::wcout << L"KB" << kbID << L':' << std::endl;
SysFreeString(kbID);
}

BSTR updateTitle;
res = update->get_Title(&updateTitle);
if (FAILED(res)) {
HandleError(L"Failed to get update title", res);
goto innerCleanup;
}
std::wcout << L" " << updateTitle << std::endl << std::endl;
SysFreeString(updateTitle);
Sleep(3000);
innerError = false;
innerCleanup:
updateKBIDs->Release();
update->Release();
if (pDownUrl != NULL) pDownUrl->Release();
if(updateTmp != NULL) updateTmp->Release();
if (downloadContent != NULL) downloadContent->Release();
if (innerError) {
goto cleanup;
}
}

ret = 0;
cleanup:
if (updates != NULL) updates->Release();
if (searchResult != NULL) searchResult->Release();
if (updateSearcher != NULL) updateSearcher->Release();
if (updateSession != NULL) updateSession->Release();
if (downloadContent != NULL) downloadContent->Release();

CoUninitialize();
return ret;
}

text highlighted with green, that section i added.

Thanks in advance.
 

Regedit32

Moderator
Joined
Mar 4, 2016
Messages
3,620
Reaction score
1,130
I haven't forgotten you - I've just been busier than expected to concentrate.

I decided to take a peek at the original coding ( excluding your addition ).

There are three goto calls that will create problems immediately, as they bypass the initialization of cleanup

I've commented these three lines out, and this is the resulting code, which will compile and run.

Code:
#include <SDKDDKVer.h>
#include <Windows.h>
#include <comdef.h>
#include <wuapi.h>

#include <string>
#include <iostream>

void HandleError(LPCWSTR message, HRESULT result)
{
    _com_error error(result);
    LPCTSTR errorText = error.ErrorMessage();
    std::wcerr << message << L": " << errorText << std::endl;
}

int main()
{
    IUpdateSession* updateSession = NULL;
    IUpdateSearcher* updateSearcher = NULL;
    ISearchResult* searchResult = NULL;
    IUpdateCollection* updates = NULL;
    HRESULT res;
    int ret = 1;

    res = CoInitializeEx(NULL, 0);
    if (FAILED(res)) {
        HandleError(L"Failed to initialize COM", res);
        return 1;
    }

    res = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&updateSession);
    if (FAILED(res)) {
        HandleError(L"Failed to create update session", res);
        //goto cleanup;
    }

    res = updateSession->CreateUpdateSearcher(&updateSearcher);
    if (FAILED(res)) {
        HandleError(L"Failed to create update searcher", res);
        //goto cleanup;
    }

    res = updateSearcher->put_IncludePotentiallySupersededUpdates(VARIANT_TRUE);
    if (FAILED(res)) {
        HandleError(L"Failed to set search options", res);
        //goto cleanup;
    }

    BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1");
    res = updateSearcher->Search(criteria, &searchResult);
    SysFreeString(criteria);
    if (FAILED(res)) {
        HandleError(L"Failed to search for updates", res);
        goto cleanup;
    }

    res = searchResult->get_Updates(&updates);
    if (FAILED(res)) {
        HandleError(L"Failed to retrieve update list from search result", res);
        goto cleanup;
    }

    LONG updateCount;
    res = updates->get_Count(&updateCount);
    if (FAILED(res)) {
        HandleError(L"Failed to get update count", res);
        goto cleanup;
    }

    for (LONG i = 0L; i < updateCount; ++i) {
        IUpdate* update = NULL;
        IStringCollection* updateKBIDs = NULL;
        bool innerError = true;

        res = updates->get_Item(i, &update);
        if (FAILED(res)) {
            HandleError(L"Failed to get update item", res);
            goto innerCleanup;
        }

        res = update->get_KBArticleIDs(&updateKBIDs);
        if (FAILED(res)) {
            HandleError(L"Failed to get KB article ID list", res);
            goto innerCleanup;
        }
        
        LONG kbIDCount;
        res = updateKBIDs->get_Count(&kbIDCount);
        if (FAILED(res)) {
            HandleError(L"Failed to get KB article ID count", res);
            goto innerCleanup;
        }

        for (LONG j = 0L; j < kbIDCount; ++j) {
            BSTR kbID;
            res = updateKBIDs->get_Item(j, &kbID);
            if (FAILED(res)) {
                HandleError(L"Failed to get KB article ID", res);
                goto innerCleanup;
            }
            std::wcout << L"KB" << kbID << L':' << std::endl;
            SysFreeString(kbID);
        }

        BSTR updateTitle;
        res = update->get_Title(&updateTitle);
        if (FAILED(res)) {
            HandleError(L"Failed to get update title", res);
            goto innerCleanup;
        }
        std::wcout << L"  " << updateTitle << std::endl << std::endl;
        SysFreeString(updateTitle);

        innerError = false;
    innerCleanup:
        updateKBIDs->Release();
        update->Release();
        if (innerError) {
            goto cleanup;
        }
    }

    ret = 0;

cleanup:
    if (updates != NULL) updates->Release();
    if (searchResult != NULL) searchResult->Release();
    if (updateSearcher != NULL) updateSearcher->Release();
    if (updateSession != NULL) updateSession->Release();

    CoUninitialize();
    return ret;
}

Lines, 34, 40 and 46 are the problem lines.

Constructing an Else {} Else if {} style code might bypass this particular issue.

When I get some more time, I'll test this with your piece of coding inserted, but taking a look at it on this Forum page the first thing that leaps out is have you defined update, updatecol, updateTMP etcetera. If not the code will certainly fail to do what you planned.
 
Joined
Nov 25, 2019
Messages
5
Reaction score
0
Hi,

Thank you for your response,
Actually my main concern is about the code I inserted because i need a download url for particular update.
I am trying to call

"res = downloadContent->get_DownloadUrl(&url); " line in my code (Highlighted with green),

Here I am not getting download url for every patch (It is working fine till windows 8.1).
meanwhile, I will made changes & check as you suggested.
Thanks
 

Regedit32

Moderator
Joined
Mar 4, 2016
Messages
3,620
Reaction score
1,130
Minor Update

I've resolved the issue with lines 34, 40 and 46, by declaring Criteria, before that nest of code.

Simply put, I've moved line 49 to line 25 as illustrated below:

Code:
#include <SDKDDKVer.h>
#include <Windows.h>
#include <comdef.h>
#include <wuapi.h>

#include <string>
#include <iostream>

void HandleError(LPCWSTR message, HRESULT result)
{
    _com_error error(result);
    LPCTSTR errorText = error.ErrorMessage();
    std::wcerr << message << L": " << errorText << std::endl;
}

int main()
{
    IUpdateSession* updateSession = NULL;
    IUpdateSearcher* updateSearcher = NULL;
    ISearchResult* searchResult = NULL;
    IUpdateCollection* updates = NULL;
    HRESULT res;
    int ret = 1;
   
    BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1");

    res = CoInitializeEx(NULL, 0);
    if (FAILED(res)) {
        HandleError(L"Failed to initialize COM", res);
        return 1;
    }

    res = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&updateSession);
    if (FAILED(res)) {
        HandleError(L"Failed to create update session", res);
        goto cleanup;
    }

    res = updateSession->CreateUpdateSearcher(&updateSearcher);
    if (FAILED(res)) {
        HandleError(L"Failed to create update searcher", res);
        goto cleanup;
    }

    res = updateSearcher->put_IncludePotentiallySupersededUpdates(VARIANT_TRUE);
    if (FAILED(res)) {
        HandleError(L"Failed to set search options", res);
        goto cleanup;
    }

    res = updateSearcher->Search(criteria, &searchResult);
    SysFreeString(criteria);
    if (FAILED(res)) {
        HandleError(L"Failed to search for updates", res);
        goto cleanup;
    }

    res = searchResult->get_Updates(&updates);
    if (FAILED(res)) {
        HandleError(L"Failed to retrieve update list from search result", res);
        goto cleanup;
    }

    LONG updateCount;
    res = updates->get_Count(&updateCount);
    if (FAILED(res)) {
        HandleError(L"Failed to get update count", res);
        goto cleanup;
    }

    for (LONG i = 0L; i < updateCount; ++i) {
        IUpdate* update = NULL;
        IStringCollection* updateKBIDs = NULL;
        bool innerError = true;

        res = updates->get_Item(i, &update);
        if (FAILED(res)) {
            HandleError(L"Failed to get update item", res);
            goto innerCleanup;
        }

        res = update->get_KBArticleIDs(&updateKBIDs);
        if (FAILED(res)) {
            HandleError(L"Failed to get KB article ID list", res);
            goto innerCleanup;
        }
       
        LONG kbIDCount;
        res = updateKBIDs->get_Count(&kbIDCount);
        if (FAILED(res)) {
            HandleError(L"Failed to get KB article ID count", res);
            goto innerCleanup;
        }

        for (LONG j = 0L; j < kbIDCount; ++j) {
            BSTR kbID;
            res = updateKBIDs->get_Item(j, &kbID);
            if (FAILED(res)) {
                HandleError(L"Failed to get KB article ID", res);
                goto innerCleanup;
            }
            std::wcout << L"KB" << kbID << L':' << std::endl;
            SysFreeString(kbID);
        }

        BSTR updateTitle;
        res = update->get_Title(&updateTitle);
        if (FAILED(res)) {
            HandleError(L"Failed to get update title", res);
            goto innerCleanup;
        }
        std::wcout << L"  " << updateTitle << std::endl << std::endl;
        SysFreeString(updateTitle);

        innerError = false;
    innerCleanup:
        updateKBIDs->Release();
        update->Release();
        if (innerError) {
            goto cleanup;
        }
    }

    ret = 0;

cleanup:
    if (updates != NULL) updates->Release();
    if (searchResult != NULL) searchResult->Release();
    if (updateSearcher != NULL) updateSearcher->Release();
    if (updateSession != NULL) updateSession->Release();

    CoUninitialize();
    return ret;
}
 
Ad

Advertisements

Regedit32

Moderator
Joined
Mar 4, 2016
Messages
3,620
Reaction score
1,130
Coming back to you additional code.

As I already stated, you have multiple undefined variables there, not to mention you start by assigning to res multiple data.

I get the feeling you are not posting your entire code, because you cannot compile or run what you have posted.

So back to my first post in this thread. It helps if you provide the full code, and not just snippets. If you are wanting help with the code, it'd make it a lot easier to see what it is I'm supposed to be addressing in its entirety.

I've been reading the Microsoft documentation with regards to the WUA API, and its one very long read. I've not across any Construct which allows you to grab the URLs yet. That's not to say its not possible; I just need to keep reading the document.

This link is just one of multiple documents available:

 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top