Sau*_*ers 5 c# windows-services windows-update windows-7 wuapi
我有许多Windows 7 PC需要使用C#控制台应用程序中的Windows Update API修补特定的Windows更新.API需要搜索已安装的更新并报告它是否已安装,如果没有则执行安装.
在Virtual 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);
}
Run Code Online (Sandbox Code Playgroud)
现在是有趣的部分.如果我从"控制面板"打开Windows Update并单击"检查更新",它会暂停一段时间,然后返回一堆安装更新.此时,如果我运行上面的代码,它按预期工作并报告超过200个已安装的更新.
看来,搜索更新的手动过程会启动/重新启动某些服务和/或其他进程,但是,我正在努力弄清楚我需要对系统做些什么来使其进入正确的状态.我希望答案是一个简单的启动服务x或使用一组args处理y的情况,但是哪个?
一些(不是全部)我尝试但没有改变行为的东西:
如果机器处于代码正确运行的状态(在我手动运行WU 之后),我注意到运行上述代码时wuauclt.exe似乎启动了.当它处于目标状态时(在我手动运行WU之前),wuauclt.exe无法启动,我无法手动启动,我怀疑这是一个很大的线索.
另一个线索是我手动运行之前的Windows Update状态.在控制面板中,Windows更新如下所示:
运行WU并通过该方法安装更新后,机器处于代码按预期运行的状态,WU看起来像:
总而言之,我需要此过程来自动安装更新.如果我检测到0已安装更新,我知道机器处于特定状态,因此我需要启动/重新启动某些进程和服务(以编程方式)以使机器在运行我的代码之前进入正确状态.知道运行/重启的是这个问题的本质.
小智 3
由于这个问题目前没有答案(尽管综合评论大多给出了答案),所以这里发生的事情如下:
这是一种非常常见的方法来检查“我是否拥有使我的程序成功运行所需的补丁?”,并且它存在短期和长期问题。
搜索代码正在执行脱机扫描(它将 IUpdateSearcher::Online 设置为 false)。这是加快搜索速度的常见策略。问题是它只处理上次在线扫描期间可用的更新。如果计算机很长时间没有进行在线扫描,那么结果就会过时。如果自上次在线扫描以来计算机的硬件或软件配置发生了显着变化,则结果将不完整。如果计算机从未进行过联机扫描,则 IUpdateSearcher::Search 不会返回错误 - 它只会立即报告没有适用的更新。
因此,如果您想尝试通过执行脱机扫描来加快速度,检查IAutomaticResults::LastSearchSuccessDate是一种很好的编码习惯,它会告诉您自动更新上次执行扫描的时间。由于自动更新扫描是在线的,因此您知道当时发生了在线扫描。如果日期已经过去几天了,您应该进行在线扫描。
此代码假设存在更新 KB123456 并且与计算机相关。但这本质上是一个有时间限制的假设,而现在的时间限制通常很短。如果 KB123456 中的补丁被整合到较新的累积更新 KB234567 中,那么在某个时候 KB123456 可能会从 Windows 更新中过期。此时,即使修补后的代码实际上位于 PC 上,您的搜索也将始终返回“未安装”。
与其尝试检查“KB X 是否已安装?”,更好的方法是测试“是否安装了我需要的修复/功能?”
如果可能的话,直接检查修复/功能。例如,如果您需要特定的新 Windows API,那么您可以使用 API Sets(如果操作系统支持),或者仅使用 LoadLibrary 和 GetProcAddress 来查看您要查找的 DLL 是否包含您需要的函数。
如果无法直接测试修复/功能,请测试 Windows 本身的状态,看看它是否是您所需要的。在 Windows 10 中,您通常只需要检查内部版本号。在旧版本的操作系统上,您可以查看 KB 的补丁说明,找出它更新的 DLL 以及将它们更新到的版本号,而不是硬编码 KB 编号,然后在运行时使用这些 DLL 名称和版本查看。
根据您正在测试的内容以及进行测试的上下文(脚本等),DISM 命令也可能会有所帮助 - 如果您需要存在特定的 Windows 软件包,则可以使用 DISM /ONLINE /GET-PACKAGES 并查看您的包是否出现在输出中。
| 归档时间: |
|
| 查看次数: |
688 次 |
| 最近记录: |