WUApiLib IUpdateInstaller2 产生错误;某些操作系统更新会安装其他操作系统会抛出 HResult



更新是从本地服务器下载的,而不是从 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公开了具有多个级别bundleUpdatesIUpdate。以前,我只是检索顶级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;
        }

相关内容

  • 没有找到相关文章

最新更新