Updates are being downloaded from a local server and not from WUS or Microsoft Repositories. Local server is Linux based which host's the contents for each update.
I'm not using UpdateDownloader
to download from Microsoft Servers, i manually download the update content and then use CopyToCache
.
These installed fine
Security Update for Microsoft .NET Framework 3.5 SP1 on Windows XP, Server 2003, Vista, Server 2008 x86 (KB2736416)
Security Update for Microsoft Visual Studio 2010 (KB2542054)
These Didn't
Security Update for Microsoft .NET Framework 4 on XP, Server 2003, Vista, Windows 7, Server 2008 x86 (KB2840628)
Update for Microsoft .NET Framework 3.5 SP1 on Windows XP, Server 2003, Vista and Server 2008 x86 (KB2836940)
How my process works
I receive this for an install from a local server which i use to download all download content for the update. (The blockquote text above KB2840628 is the example provided below)
{
"app_uris": [
{
"file_name": "msipatchregfix-x86_94a84b80b8b45a1ac53a0e5d085513da0f099655.exe",
"file_uri": "https://192.168.5.108/packages/d13c13c81f94fbb48f39c817a71ff239a31773d3a0e821a968dc42a913892841/msipatchregfix-x86_94a84b80b8b45a1ac53a0e5d085513da0f099655.exe",
"file_size": 130600
},
{
"file_name": "ndp40-kb2840628-v2-x86_891d50ff3c1322db3fb0fde222ebb0aaa5260272.exe",
"file_uri": "https://192.168.5.108/packages/d13c13c81f94fbb48f39c817a71ff239a31773d3a0e821a968dc42a913892841/ndp40-kb2840628-v2-x86_891d50ff3c1322db3fb0fde222ebb0aaa5260272.exe",
"file_size": 13294216
}
],
"app_id": "d13c13c81f94fbb48f39c817a71ff239a31773d3a0e821a968dc42a913892841",
"app_name": "Security Update for Microsoft .NET Framework 4 on XP, Server 2003, Vista, Windows 7, Server 2008 x86 (KB2840628)"
}
With that said, the problem is that some updates install perfectly fine, but certain updates (I believe the ones that have more than one bundle-updates
) don't go thru, its driving me mad!
I first download each Uri
and then load them into the update with CopyToCache
.
var collection = new UpdateCollection();
IList<string> updateFiles = Directory.GetFiles(updateFolder);
var fileCollection = new StringCollection();
try
{
foreach (var file in updateFiles)
fileCollection.Add(file);
//Error happens here on certain updates. Not all.
((IUpdate2)update.BundledUpdates[0]).CopyToCache(fileCollection);
collection.Add(update);
return collection;
}
catch (Exception e)
{
return null;
}
After this, the returned collection is passed through my WindowsUpdateInstaller
Method shown below:
IUpdateSession Session = new UpdateSession();
var updatesToInstall = //THIS GETS THE RETURN FROM THE ABOVE CODE...
var installer = (IUpdateInstaller2)Session.CreateUpdateInstaller();
installer.ForceQuiet = true;
installer.AllowSourcePrompts = false;
installer.Updates = updatesToInstall;
foreach (IUpdate updateNode in installer.Updates)
{
updateNode.AcceptEula();
}
//FAILS HERE WITH "-2145124318, Result code: orcFailed",
var installationRes = installer.Install();
var installResult = installationRes.GetUpdateResult(0);
The update installs just fine if i manually double click on the executable it and install it manually without using the code.
It appears that the WUApi
exposes IUpdate
which holds multiple levels of bundleUpdates
. Before, I was simply retrieving the top level of bundleUpdates
which by doing so, made certain updates fail due to missing content required by the update; most windows updates have more than 1 level of bundles.
For example, imagine this tree like structure for 1 Update (aka IUpdate):
Update 1
---> Bundle 1
*URL 1
*URL 2
----> Bundle 1A
*URL 1
*URL 2
*URL 3
---> Bundle 2
*URL 1
----> Bundle 2A
*URL 1
*URL 2
----> Bundle 2B
*URL 1
----> Bundle 3
*URL 1
----> Bundle 3A
*URL 1
*URL 2
My Solution was to create a Recursive function to parse each update individually and keep all URIs in a dictionary of key type "bundleName
" and list of value
s that will hold all URIs for that particular bundle.
Like So:
Dictionary<string, List<string>>
The Recursive function is the following:
private static Dictionary<string, List<string>> GetAllUpdates(IUpdate iUpdate)
{
var bundleDict = new Dictionary<string, List<string>>();
foreach (IUpdate bundle in iUpdate.BundledUpdates)
{
foreach (IUpdateDownloadContent udc in bundle.DownloadContents)
{
var downloadContents = new List<string>();
if (String.IsNullOrEmpty(udc.DownloadUrl))
continue;
var url = udc.DownloadUrl;
downloadContents.Add(url);
if (!bundleDict.ContainsKey(bundle.Title))
bundleDict.Add(bundle.Title, downloadContents);
}
if (bundle.BundledUpdates.Count > 0)
{
var valuesReturned = GetAllUpdates(bundle);
foreach (var data in valuesReturned)
{
if(!bundleDict.ContainsKey(data.Key))
bundleDict.Add(data.Key, data.Value);
}
}
}
return bundleDict;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With