使用WUAPILib安装Windows更新后,更新仍显示为待处理
Windows更新安装后WU界面状态不刷新问题
问题描述
使用自定义的WindowsUpdate类安装Windows更新时,更新已完成下载和安装,但Windows Update(WU)图形界面仍显示未安装状态,点击界面中的“立即安装”按钮后才会刷新显示已安装。调试日志显示更新确实安装成功,询问是否需要使用不同版本的IUpdateInstaller来解决此问题。
自定义WindowsUpdate类代码
class WindowsUpdate:IDownloadProgressChangedCallback,IDownloadCompletedCallback, IInstallationCompletedCallback, IInstallationProgressChangedCallback { public static UpdateSession session = new UpdateSession(); public UpdateCollection neededUpdates = new UpdateCollection(); UpdateDownloader downloader = session.CreateUpdateDownloader(); IUpdateInstaller installer = session.CreateUpdateInstaller(); public Status currentStatus; bool enableDebugLogging = false; bool enableInstall = true; bool enableDownload = true; public bool rebootPending = false; public List<string> messages = new List<string>(); public void checkForUpdates() { debugLog("New WU: Checking for Updates"); currentStatus = Status.Starting; IUpdateSearcher searcher = session.CreateUpdateSearcher(); ISearchResult results = searcher.Search("IsInstalled=0 AND IsHidden=0"); debugLog(string.Format("{0} Updates Found", results.Updates.Count)); downloader.Updates = new UpdateCollection(); for (int x = 0; x < results.Updates.Count; x++) { IUpdate u = results.Updates[x]; if (!u.EulaAccepted) { u.AcceptEula(); } neededUpdates.Add(u); debugLog(string.Format("Update {0} Needed", u.Title)); if (!u.IsDownloaded) { debugLog(string.Format("Adding {0} To the WU Download Queue", u.Title), false); downloader.Updates.Add(u); debugLog(string.Format("Added {0} To the WU Download Queue", u.Title)); } } debugLog("New WU: Search Complete"); if (downloader.Updates.Count > 0 && enableDownload) { downloadUpdates(); }else if(downloader.Updates.Count == 0 && results.Updates.Count > 0) { debugLog(string.Format("{0} Updates, None pending download", downloader.Updates.Count)); if (enableInstall) { debugLog("Queing Install"); } installUpdates(); }else if(!enableDownload && downloader.Updates.Count > 0) { debugLog(string.Format("{0} Updates Pending Download, Download Not Enabled", downloader.Updates.Count)); }else if(neededUpdates.Count == 0) { currentStatus = Status.Ready; } } void installUpdates() { debugLog(string.Format("Beginning Installation of {0} Updates", neededUpdates.Count)); installer.Updates = neededUpdates; installer.BeginInstall(this, this, null); } void downloadUpdates() { debugLog(string.Format("Beginning Download of {0} Updates", downloader.Updates.Count)); IDownloadJob job = downloader.BeginDownload(this, this, null); } void IDownloadCompletedCallback.Invoke(IDownloadJob downloadJob, IDownloadCompletedCallbackArgs callbackArgs) { debugLog("Download Completed Callback"); foreach (IUpdate u in downloadJob.Updates) { debugLog(string.Format("{0} Download Completed", u.Title)); } debugLog("All Updates Downloaded, Beginning Install"); currentStatus = Status.Installing; installUpdates(); } void IDownloadProgressChangedCallback.Invoke(IDownloadJob downloadJob, IDownloadProgressChangedCallbackArgs callbackArgs) { debugLog("Download Status Callback", false); currentStatus = Status.Downloading; IDownloadProgress progress = callbackArgs.Progress; debugLog(string.Format("WUA_DownloadingProgress:{0}|{1}|{2}", progress.CurrentUpdateIndex + 1, progress.CurrentUpdatePercentComplete, progress.PercentComplete), false); } void IInstallationCompletedCallback.Invoke(IInstallationJob installationJob, IInstallationCompletedCallbackArgs callbackArgs) { debugLog("Install Complete Callback"); foreach(IUpdate u in installationJob.Updates) { debugLog(string.Format("Installation Complete: {0}", u.Title)); } debugLog("Ending WU Install", false); IInstallationResult installationResult = installer.EndInstall(installationJob); debugLog("After Installer Ended", false); if (installationResult.RebootRequired) { debugLog("Reboot Required, Setting Flag", false); rebootPending = true; } debugLog("Starting Cleanup"); //installationJob.CleanUp(); debugLog("Ending Cleanup"); currentStatus = Status.Installed; } void IInstallationProgressChangedCallback.Invoke(IInstallationJob installationJob, IInstallationProgressChangedCallbackArgs callbackArgs) { debugLog("Install Progress Callback", false); currentStatus = Status.Installing; IInstallationProgress p = callbackArgs.Progress; debugLog(string.Format("Installation Progress: {0} {1} {2}", p.CurrentUpdateIndex + 1, p.CurrentUpdatePercentComplete, p.PercentComplete), false); } void debugLog(string message, bool showInResults = true) { if (enableDebugLogging) { Logging.WriteToTextLog(message); } if (showInResults) { messages.Add(message); } } public enum Status { Starting = 0, Ready = 1, Downloading = 2, Installing = 3, Installed = 4 } public WindowsUpdate(bool logging, bool install) { enableDebugLogging = logging; enableInstall = install; currentStatus = Status.Starting; debugLog("WU Instance Called"); } public string getStatus() { StringBuilder sb = new StringBuilder(); foreach(string s in messages) { sb.Append(s); sb.Append(Environment.NewLine); } return sb.ToString(); } }
解决方案
这个问题和IUpdateInstaller版本无关,根源是Windows Update界面依赖的本地更新状态缓存没有被同步更新。手动点击“立即安装”时,WU界面会触发一次重新搜索,从而刷新了状态。
具体修复步骤
在安装完成的回调方法IInstallationCompletedCallback.Invoke末尾,添加强制刷新WU状态缓存的逻辑:
// 刷新WU本地状态缓存,让界面同步最新安装状态 IUpdateSearcher refreshSearcher = session.CreateUpdateSearcher(); try { refreshSearcher.Search("IsInstalled=1"); // 执行搜索触发缓存更新 debugLog("WU状态缓存已刷新"); } catch (Exception ex) { debugLog($"刷新缓存失败: {ex.Message}"); }
原理说明
执行UpdateSearcher.Search操作会让Windows Update Agent(WUA)重新查询系统的更新状态,并更新本地缓存。WU界面在读取状态时会优先使用这个缓存,因此刷新后就能显示正确的安装状态,无需手动点击“立即安装”。
备选方案(不推荐)
如果上述方法无效,可以尝试重启Windows Update服务(wuauserv),但这种方式会中断正在进行的WU相关操作,仅作为最后手段:
using (var serviceController = new ServiceController("wuauserv")) { if (serviceController.Status == ServiceControllerStatus.Running) { serviceController.Stop(); serviceController.WaitForStatus(ServiceControllerStatus.Stopped); serviceController.Start(); serviceController.WaitForStatus(ServiceControllerStatus.Running); debugLog("Windows Update服务已重启"); } }
内容的提问来源于stack exchange,提问作者jpats22011
相关产品推荐
相关产品推荐

