更新是从本地服务器下载的,而不是从 WUS 或Microsoft存储库下载的。本地服务器基于 Linux 的主机每次更新的内容。
我没有使用UpdateDownloader
从Microsoft服务器下载,而是手动下载更新内容,然后使用CopyToCache
。
这些安装很好
Windows XP、Server 2003、Vista、Server 2008 x86 x86 (KB2736416( 上的 Microsoft .NET Framework 3.5 SP1 安全更新程序
Microsoft Visual Studio 2010 安全更新程序 (KB2542054(
这些没有
XP 版 Microsoft .NET Framework 4 安全更新程序,服务器 2003, Vista, 视窗 7, 服务器 2008 x86 (KB2840628(
Windows XP、Server 2003、Vista 和 Server 2008 x86 上的 Microsoft .NET Framework 3.5 SP1 更新 (KB2836940(
我的流程如何运作
我收到这个是从本地服务器安装的,我用它来下载更新的所有下载内容。(上面的块引用文本KB2840628是下面提供的示例(
{
"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<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;
}
在此之后,返回的集合通过如下所示的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
公开了具有多个级别bundleUpdates
的IUpdate
。以前,我只是检索顶级bundleUpdates
这样做会使某些更新由于缺少更新所需的内容而失败;大多数 Windows 更新都有 1 个以上的捆绑包级别。
例如,想象一下 1 更新(又名 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<string, List<string>>
递归函数如下:
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;
}