我有许多Windows 7 PC需要使用C#控制台应用中的Windows Update API修补特定的Windows更新。 API需要搜索已安装的更新并报告它是否已安装,如果没有则执行安装。
在虚拟PC(Windows 7 Professional Hyper-v客户端)上进行测试时,我遇到类似于目标PC(Windows 7 Embedded)的情况,其中以下代码返回(非常快速且没有任何例外)0更新。我知道这是错的。事实上,它甚至在我安装.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或使用一组args处理y的情况,但是哪个?
我尝试但未改变行为的一些(并非所有)事情:
如果机器处于代码正常运行的状态( 之后我手动运行WU),我注意到上面的代码运行时,wuauclt.exe似乎启动了。当它处于目标状态时(在我手动运行WU之前),wuauclt.exe无法启动,我无法手动启动,我怀疑这是一个很大的线索。
另一个线索是我手动运行之前的Windows Update状态。在控制面板中,Windows更新如下所示:
运行WU并通过该方法安装更新后,机器处于代码按预期运行的状态,WU看起来像:
总而言之,我需要此过程来自动安装更新。如果我检测到0已安装更新,我知道机器处于特定状态,因此我需要启动/重新启动某些进程和服务(以编程方式)以使机器在运行我的代码之前进入正确状态。知道运行/重启的内容是这个问题的本质。
答案 0 :(得分:1)
由于此问题目前尚无答案(尽管合并的注释大多给出了答案),所以这里是发生的情况:
这是检查“我是否拥有使程序成功运行所需的补丁程序”的一种非常常用的方法,并且它有短期和长期的问题。
短期问题:
搜索代码正在执行脱机扫描(将IUpdateSearcher :: Online设置为false)。这是加快搜索速度的常见策略。问题在于它仅处理在先前的联机扫描期间可用的更新。如果计算机没有经过一段时间的在线扫描,则结果将是陈旧的。如果自上次联机扫描以来计算机的硬件或软件配置发生了显着变化,则结果将不完整。如果计算机从未进行过在线扫描,则IUpdateSearcher :: Search不会返回错误-它将立即报告没有更新可用。
因此,如果您想尝试通过脱机扫描来加快速度,那么检查IAutomaticResults::LastSearchSuccessDate是一个很好的编码做法,它告诉您上次自动更新进行扫描的情况。由于“自动更新”扫描处于联机状态,因此您知道当时进行了联机扫描。如果日期已超过几天,则应该进行在线扫描。
长期问题:
此代码假定存在更新KB123456,并且与计算机有关。但这本质上是一个有时间限制的假设,这些天的时间限制通常很短。如果KB123456中的修补程序滚动到了较新的累积更新KB234567中,则KB123456可能会在Windows Update中过期。届时,即使修补程序代码实际上在PC上,您的搜索也将始终返回“未安装”。
代替尝试检查“是否已安装KB X?”,更好的方法是测试“是否需要安装修订/功能?”
如果可能,请直接检查修复/功能。例如,如果需要特定的新Windows API,则可以在操作系统支持的情况下使用“ API集”,或者仅使用LoadLibrary和GetProcAddress来查看所需的DLL是否包含所需的功能。
< / li>如果无法直接测试修复/功能,请测试Windows本身的状态以查看是否需要它。在Windows 10中,您通常只需要检查内部版本号。在较旧版本的OS上,您可以查看KB的补丁说明,了解其更新的DLL以及将其更新到的版本号,而不是对KB号进行硬编码,然后在运行时使用这些DLL名称和版本。校验。
取决于您要测试的内容以及进行测试的环境(脚本等),DISM命令也可能会有所帮助-如果您需要特定的Windows软件包,目前,您可以使用DISM / ONLINE / GET-PACKAGES来查看您的软件包是否出现在输出中。