簡體   English   中英

使用 C# 的 Windows Update API 未找到任何已安裝的更新

[英]Windows Update API with C# not finding any installed updates

我有許多 Windows 7 PC 需要使用特定 Windows 更新進行修補,使用 C# 控制台應用程序中的 Windows 更新 API。 API 需要搜索已安裝的更新,如果已經安裝則返回報告,如果沒有則執行安裝。

在虛擬 PC(Windows 7 Professional Hyper-v 客戶端)上進行測試時,我遇到了與目標 PC(Windows 7 Embedded)類似的情況,其中以下代碼返回(非常快且無任何例外)0 更新。 我知道這是錯誤的。 事實上,它甚至在我安裝 a.msu 更新后返回這個。

代碼:

 UpdateSession uSession = new UpdateSession();
 IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
 uSearcher.Online = false;
 try
 {
    ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
    Console.WriteLine("Found " + sResult.Updates.Count + " updates");
    foreach (IUpdate update in sResult.Updates)
    {
       Console.WriteLine(update.Title);
       if (update.Title.ToLower().Contains("kb123456")) {
        //Update is not required
        ReportInstalled();
        return;
       }
     }
     //If we get here, the update is not installed
     InstallUpdate();
  }
  catch (Exception ex)
  {
    Console.WriteLine("Something went wrong: " + ex.Message);
  }

現在是有趣的部分。 如果我從控制面板打開 Windows Update 並單擊“檢查更新”,它會關閉一段時間然后返回並安裝一堆更新。 此時,如果我運行上面的代碼,它會按預期工作並報告超過 200 個已安裝的更新。

似乎搜索更新的手動過程會啟動/重新啟動某些服務和/或其他進程,但是,我正在努力弄清楚我需要對系統做什么才能使其進入正確狀態。 我希望答案是啟動服務 x 或使用一組參數處理 y 的簡單情況,但是哪個?

我嘗試過但沒有改變行為的一些(不是全部)事情:

  1. 啟動 BITS 服務,重新啟動 Windows 更新服務
  2. 嘗試使用各種開關啟動 wuauclt.exe(在評論中記錄在此處

在機器處於代碼正確運行的狀態下(我手動運行 WU 之后),我注意到在運行上述代碼時進程 wuauclt.exe 似乎啟動了。 當它處於目標狀態時(在我手動運行 WU 之前),wuauclt.exe 不會啟動,我無法手動啟動它,我懷疑這是一個很大的線索。

另一條線索是在我手動運行之前 Windows 更新的狀態。 在控制面板中,Windows 更新如下所示:

在此處輸入圖像描述

在運行 WU 並通過該方法安裝更新后,機器處於代碼按預期 WU 運行的狀態,如下所示:

在此處輸入圖像描述

總而言之,我需要這個過程來自動安裝更新。 如果我檢測到 0 個已安裝更新,我知道機器處於特定狀態,因此我需要啟動/重新啟動一些進程和服務(以編程方式)以使機器進入正確狀態,然后再運行我的代碼。 知道要運行/重啟什么是這個問題的本質。

由於這個問題目前沒有答案(盡管綜合評論大多給出了答案),這里發生了什么:

這是一種非常常見的檢查“我是否有我的程序成功運行所需的補丁?”的方法,它有一個短期和一個長期的問題。

短期問題:

搜索代碼正在進行離線掃描(它將 IUpdateSearcher::Online 設置為 false)。 這是加快搜索速度的常用策略。 問題是它只處理上一次在線掃描期間可用的更新。 如果計算機多年未進行在線掃描,則結果將過時。 如果計算機自上次在線掃描后硬件或軟件配置發生了顯着變化,則結果將不完整。 如果計算機從未進行過在線掃描,那么 IUpdateSearcher::Search 將不會返回錯誤——它只會立即報告沒有適用的更新。

因此,如果您想嘗試通過執行離線掃描來加快速度,那么檢查IAutomaticResults::LastSearchSuccessDate是一種很好的編碼習慣,它會告訴您上次自動更新執行掃描的時間。 由於自動更新掃描是聯機的,因此您知道當時發生了聯機掃描。 如果日期超過幾天,您應該進行在線掃描。

長期問題:

此代碼假定更新 KB123456 存在並且與計算機相關。 但這本質上是一個有時間限制的假設,而現在的時間限制通常很短。 如果 KB123456 中的補丁被納入更新的累積更新 KB234567,那么 KB123456 可能會在某個時候從 Windows 更新中過期。 那時您的搜索將始終返回“未安裝”,即使修補代碼實際上在 PC 上也是如此。

結論

與其嘗試檢查“是否安裝了 KB X?”,更好的方法是測試“是否安裝了我需要的修復程序/功能?”

  • 如果可能的話,直接檢查修復/功能。 例如,如果您需要一個特定的新 Windows API,那么您可以在操作系統支持的情況下使用 API 集,或者只使用 LoadLibrary 和 GetProcAddress 來查看您使用的 DLL 是否包含您需要的函數。

  • 如果無法直接測試修復/功能,則測試 Windows 本身的狀態以查看它是否是您需要的。 在 Windows 10 中,您通常只需要檢查內部版本號。 在舊版本的操作系統上,您可以查看 KB 的補丁說明,而不是硬編碼 KB 編號,找出它更新了哪些 DLL 以及將它們更新到什么版本號,然后將這些 DLL 名稱和版本用於您的運行時查看。

  • 取決於您正在測試的內容和您進行測試的環境(腳本等),DISM 命令也可能有用——如果您需要特定的 Windows 包,您可以使用 DISM /ONLINE /GET-PACKAGES 並查看您的包是否出現在輸出中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM