使用 C# 与 Windows 更新交互
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/922132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use C# to interact with Windows Update
提问by DevinB
Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
是否有任何 API 可以编写可以与 Windows 更新交互的 C# 程序,并使用它来有选择地安装某些更新?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
我正在考虑将列表存储在已批准更新的中央存储库中。然后客户端应用程序(必须安装一次)将与 Windows 更新交互以确定哪些更新可用,然后安装在批准列表中的那些。这样,更新仍会从客户端的角度自动应用,但我可以选择应用哪些更新。
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
顺便说一下,这不是我在公司的角色,我真的只是想知道是否有用于 Windows 更新的 API 以及如何使用它。
采纳答案by Christoph Grimmer-Dietrich
Add a Reference to WUApiLib to your C# project.
向 C# 项目添加对 WUApiLib 的引用。
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspxfor more documentation.
鉴于您有一个带有 TextBox 的表单,这将为您提供当前安装的更新列表。有关更多文档,请参阅http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx。
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
但是,这将不允许您找到不是通过 Windows 更新分发的 KB 修补程序。
回答by Ryan Bolger
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
做你想做的最简单的方法是使用WSUS。它是免费的,基本上可以让您设置自己的本地 Windows 更新服务器,您可以在其中决定哪些更新是“批准”用于您的计算机的。WSUS 服务器和客户端都不需要在域中,但如果客户端在,它可以更轻松地配置客户端。如果您有不同的机器组需要批准不同的更新组,这也受支持。
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
这不仅可以实现您的既定目标,还可以通过仅从 WSUS 服务器下载一次更新来节省您的整体网络带宽。
回答by P-L
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
如果在您的上下文中您被允许使用 Windows 服务器更新服务 ( WSUS),它将使您能够访问Microsoft.UpdateServices.Administration 命名空间。
From there, you should be able to do some nice things :)
从那里,您应该能够做一些不错的事情:)
回答by Xavius Pupuss
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits). Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
对。我首先尝试了 Christoph Grimmer-Die 方法,但在某些情况下,它不起作用。我猜这是由于不同版本的 .net 或操作系统架构(32 或 64 位)。然后,为了确保我的程序始终获得我的每个计算机域的 Windows 更新等待列表,我执行了以下操作:
- Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
- 使用 WSUS 安装服务器(可能会节省一些互联网带宽):http: //www.microsoft.com/en-us/download/details.aspx?displaylang=en& id=5216
将所有工作站和服务器添加到 WSUS 服务器
获取 SimpleImpersonation Lib 以使用不同的管理员权限运行此程序(可选)
在您的开发工作站上仅安装管理控制台组件并运行以下程序:
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
它将在控制台中使用 UpdateInstallationStates.Downloaded 打印所有 Windows 更新
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}