简体   繁体   English

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

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

I have a number of Windows 7 PC's that need patching with a particular Windows update, using the Windows Update API in a C# console app.我有许多 Windows 7 PC 需要使用特定 Windows 更新进行修补,使用 C# 控制台应用程序中的 Windows 更新 API。 The API needs to search the installed updates and report back if it's already installed and perform the installation if not. API 需要搜索已安装的更新,如果已经安装则返回报告,如果没有则执行安装。

Whilst testing on a Virtual PC (Windows 7 Professional Hyper-v client) I have a situation similar to the target PCs (Windows 7 Embedded) where the following code returns (very quickly and without any exceptions) 0 updates.在虚拟 PC(Windows 7 Professional Hyper-v 客户端)上进行测试时,我遇到了与目标 PC(Windows 7 Embedded)类似的情况,其中以下代码返回(非常快且无任何例外)0 更新。 Which I know to be wrong.我知道这是错误的。 In fact, it even returns this after I install a.msu update.事实上,它甚至在我安装 a.msu 更新后返回这个。

Code:代码:

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

Now for the fun part.现在是有趣的部分。 If I open up the Windows Update from the Control Panel and click 'Check for updates', it goes off for a while and comes back with a bunch of updates to install.如果我从控制面板打开 Windows Update 并单击“检查更新”,它会关闭一段时间然后返回并安装一堆更新。 At this point, if I run the above code, it works as expected and reports over 200 installed updates.此时,如果我运行上面的代码,它会按预期工作并报告超过 200 个已安装的更新。

It appears that the manual process of searching for updates starts/restarts some services and/or other processes, however, I am struggling to figure out exactly what I need to do to the system to get it into the correct state.似乎搜索更新的手动过程会启动/重新启动某些服务和/或其他进程,但是,我正在努力弄清楚我需要对系统做什么才能使其进入正确状态。 I expect the answer will be a simple case of starting service x or process y with a set of args, but which?我希望答案是启动服务 x 或使用一组参数处理 y 的简单情况,但是哪个?

Some (not all) of the things I have tried but did not alter the behavior:我尝试过但没有改变行为的一些(不是全部)事情:

  1. Started the BITS service, restarted Windows Update Service启动 BITS 服务,重新启动 Windows 更新服务
  2. Tried launching wuauclt.exe with various switches (documented here in the comments)尝试使用各种开关启动 wuauclt.exe(在评论中记录在此处

With the machine in a state where the code runs correctly ( after I run WU manually), I have noticed the process wuauclt.exe appears to start when the above code is run.在机器处于代码正确运行的状态下(我手动运行 WU 之后),我注意到在运行上述代码时进程 wuauclt.exe 似乎启动了。 When it's in the target state (before I run WU manually), wuauclt.exe does not start, and I am not able to launch this manually, I suspect this is a big clue.当它处于目标状态时(在我手动运行 WU 之前),wuauclt.exe 不会启动,我无法手动启动它,我怀疑这是一个很大的线索。

One other clue is the state of Windows Update before I run it manually.另一条线索是在我手动运行之前 Windows 更新的状态。 In the control panel windows update looks like this:在控制面板中,Windows 更新如下所示:

在此处输入图像描述

After running WU and installing updates via that method, and the machine is in a state where the code runs as expected WU looks like:在运行 WU 并通过该方法安装更新后,机器处于代码按预期 WU 运行的状态,如下所示:

在此处输入图像描述

To sum up, I need this process to automate the installation of an update.总而言之,我需要这个过程来自动安装更新。 If I detect 0 installed updates, I know the machine is in a particular state, so I will need to launch/restart some processes and services (programmatically) to get the machine into the correct state before running my code.如果我检测到 0 个已安装更新,我知道机器处于特定状态,因此我需要启动/重新启动一些进程和服务(以编程方式)以使机器进入正确状态,然后再运行我的代码。 Knowing what to run/restart is the essence of this problem.知道要运行/重启什么是这个问题的本质。

Since this question doesn't have an answer at the moment (though the combined comments mostly give the answer), here's what happened here:由于这个问题目前没有答案(尽管综合评论大多给出了答案),这里发生了什么:

This is a very common approach to checking "Do I have the patches I need in order for my program to run successfully?", and it has a short-term and a long-term problem.这是一种非常常见的检查“我是否有我的程序成功运行所需的补丁?”的方法,它有一个短期和一个长期的问题。

The short-term problem:短期问题:

The search code is doing an offline scan (it's setting IUpdateSearcher::Online to false).搜索代码正在进行离线扫描(它将 IUpdateSearcher::Online 设置为 false)。 That's a common tactic to speed up the search.这是加快搜索速度的常用策略。 The problem is that it only processes updates that were available during the previous online scan.问题是它只处理上一次在线扫描期间可用的更新。 If the computer hasn't done an online scan in ages, then the results will be stale.如果计算机多年未进行在线扫描,则结果将过时。 If the computer has had a notable hardware or software configuration change since the last online scan, then the results will be incomplete.如果计算机自上次在线扫描后硬件或软件配置发生了显着变化,则结果将不完整。 If the computer has never done an online scan, then IUpdateSearcher::Search won't return an error -- it will just instantly report that no updates are applicable.如果计算机从未进行过在线扫描,那么 IUpdateSearcher::Search 将不会返回错误——它只会立即报告没有适用的更新。

So if you want to try to speed things up by doing an offline scan, it's good coding practice to check IAutomaticResults::LastSearchSuccessDate , which tells you the last time that Automatic Updates did a scan.因此,如果您想尝试通过执行离线扫描来加快速度,那么检查IAutomaticResults::LastSearchSuccessDate是一种很好的编码习惯,它会告诉您上次自动更新执行扫描的时间。 Since Automatic Updates scans are online, you know that an online scan occurred at that time.由于自动更新扫描是联机的,因此您知道当时发生了联机扫描。 If the date is more than a few days old, you should do an online scan instead.如果日期超过几天,您应该进行在线扫描。

The long-term problem:长期问题:

This code is assuming that an update KB123456 exists and is relevant to the computer.此代码假定更新 KB123456 存在并且与计算机相关。 But that's inherently a time-limited assumption, and the time limit these days is often quite short.但这本质上是一个有时间限制的假设,而现在的时间限制通常很短。 If the patches in KB123456 get rolled into a newer cumulative update KB234567, then at some point KB123456 may be expired from Windows Update.如果 KB123456 中的补丁被纳入更新的累积更新 KB234567,那么 KB123456 可能会在某个时候从 Windows 更新中过期。 At that point your search will always return "not installed", even if the patched code is actually on the PC.那时您的搜索将始终返回“未安装”,即使修补代码实际上在 PC 上也是如此。

Conclusion结论

Instead of trying to check "Is KB X installed?", the better approach is to test "Is the fix/feature I need installed?"与其尝试检查“是否安装了 KB X?”,更好的方法是测试“是否安装了我需要的修复程序/功能?”

  • If at all possible, check for the fix/feature directly.如果可能的话,直接检查修复/功能。 For example, if you need a particular new Windows API, then you can use API Sets if the OS supports it, or just use LoadLibrary and GetProcAddress to see if the DLL you're after contains the function you need.例如,如果您需要一个特定的新 Windows API,那么您可以在操作系统支持的情况下使用 API 集,或者只使用 LoadLibrary 和 GetProcAddress 来查看您使用的 DLL 是否包含您需要的函数。

  • If testing directly for the fix/feature isn't possible, then test the state of Windows itself to see if it's what you need.如果无法直接测试修复/功能,则测试 Windows 本身的状态以查看它是否是您需要的。 In Windows 10, you often just need to check the build number.在 Windows 10 中,您通常只需要检查内部版本号。 On older versions of the OS, instead of hardcoding a KB number, you can look at the patch notes for the KB, find out what DLLs it updates and what version numbers it updates them to, then use those DLL names and versions for your runtime check.在旧版本的操作系统上,您可以查看 KB 的补丁说明,而不是硬编码 KB 编号,找出它更新了哪些 DLL 以及将它们更新到什么版本号,然后将这些 DLL 名称和版本用于您的运行时查看。

  • Depending on exactly what you're testing and the context in which you're doing the test (scripting, etc.), the DISM command may also be helpful -- if you need a particular Windows package to be present, you can use DISM /ONLINE /GET-PACKAGES and see if your package shows up in the output.取决于您正在测试的内容和您进行测试的环境(脚本等),DISM 命令也可能有用——如果您需要特定的 Windows 包,您可以使用 DISM /ONLINE /GET-PACKAGES 并查看您的包是否出现在输出中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM