WUApiLib IUpdateInstaller2产生错误; 一些操作系统更新安装其他人扔HResult -2145124318

正在从本地服务器而不是从WUS或Microsoft存储库下载更新。 本地服务器是基于Linux的,主机是每次更新的内容。

我没有使用UpdateDownloader从Microsoft Servers下载,我手动下载更新内容,然后使用CopyToCache

这些装好了

Windows XP,Server 2003,Vista,Server 2008 x86上的Microsoft .NET Framework 3.5 SP1安全更新程序(KB2736416)

Microsoft Visual Studio 2010安全更新程序(KB2542054)

这些没有

XP,Server 2003,Vista,Windows 7,Server 2008 x86上的Microsoft .NET Framework 4安全更新程序(KB2840628)

Windows XP,Server 2003,Vista和Server 2008 x86上的Microsoft .NET Framework 3.5 SP1更新(KB2836940)

我的流程如何运作

我从本地服务器收到此安装,我用它来下载更新的所有下载内容。 (KB2840628上面的blockquote文本是下面提供的示例)

 { "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)" } 

话虽如此,问题是一些更新安装完全正常,但某些更新(我相信那些有多个bundle-updates )不会通过,它让我疯了!

我首先下载每个Uri ,然后使用CopyToCache它们加载到更新中。

  var collection = new UpdateCollection(); IList 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; } 

在此之后,返回的集合将通过我的WindowsUpdateInstaller方法传递,如下所示:

 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); 

如果我手动双击可执行文件并手动安装它而不使用代码,则更新安装就可以了。

似乎WUApi暴露了IUpdate ,它拥有多个级别的bundleUpdates 。 以前,我只是检索bundleUpdates的顶级bundleUpdates ,这样做会导致某些更新因更新所需内容丢失而失败; 大多数Windows更新都有超过1级的捆绑。

例如,假设这个树类似于1 Update(又名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 

我的解决方案是创建一个递归函数来单独解析每个更新,并将所有URI保存在密钥类型“ bundleName ”的字典中,以及将保存该特定包的所有URI list of value

喜欢如此:

 Dictionary> 

递归函数如下:

  private static Dictionary> GetAllUpdates(IUpdate iUpdate) { var bundleDict = new Dictionary>(); foreach (IUpdate bundle in iUpdate.BundledUpdates) { foreach (IUpdateDownloadContent udc in bundle.DownloadContents) { var downloadContents = new List(); 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; }