分享
 
 
 

.NET和智能传输服务API编写自动更新程序

王朝c#·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

我必须承认,我喜欢 Windows? Update 功能。 在我的计算机开机的时间中,大约有 85% 的时间都连接到了 Internet 上,但是,像许多人一样,我当然不会这么多时间都在使用网络。 Windows XP 利用了这一未用的带宽,将网上可用的最新服务包和修补程序与我计算机上已安装的服务包和修补程序进行比较。 如果它找到了我需要的更新,便会在后台将它们下载下来。 完成后,Windows 会通知我计算机上有需要安装的新软件包。

如果可以选择的话,我希望让客户端上的每一个应用程序都像 Windows 一样允许自动更新。 现在有许多有利的条件以及现成的连接来实现这一功能。 如果要使应用程序自动进行自我更新,必须编写代码来处理发现、下载、安全性以及替换等方面的问题。

为了处理实际的下载,我将介绍 Windows 的一项新功能:后台智能传输服务 (BITS)。 在讨论此功能之后,我将介绍 .NET Framework 中可用来解决自动更新应用程序的安全性和替换问题的功能。

请注意,虽然 BITS 1.5 可重新发布软件可以很好地工作在 Windows 2000 和 Windows XP 上,但是 Microsoft 不打算在 Windows 9x 或 Windows Me 上支持 BITS API。 BITS 有望作为 Windows 的将来版本的一个组件提供。

但是,在开始下面的内容之前,需要指出的重要一点是:要使您的应用程序能够使用本文所介绍的技术,需要在 .NET 下对它进行管理。 BITS 自身是操作系统的一部分,而这里介绍的 .NET Framework 技术可以用于非托管的应用程序的自动更新功能。

困难

为了找到远程服务器上的更新,您的应用程序需要一种查询网络的手段。 这需要网络代码以及使应用程序和服务器可以用来彼此通信的简单协议。 我将在本文的后面继续探讨“发现”这个话题。

接下来您还必须能够下载软件包。 由于 .NET 在网络方面驾轻就熟,因此下载可能看上去不像是一个大问题,但是下载用户所请求的文件仅仅是一个方面。另一个方面是在未经用户同意的情况下下载大型文件。 礼貌的自动更新应用程序仅仅使用残留的带宽来下载更新。 这听起来很不错,但是,您会看到,它带来了一个相当困难的技术问题。 幸运的是,相应的解决方案已存在。

安全可能是首当其冲的一个问题。 请花一点时间想一想 Windows Update 功能。 它的一个主要目的是获取安全修补程序。 想想,如果 Windows Update 自身都不能确认它安装的是否是安全的代码,情况会怎么样? 显而易见,从 Internet 上下载代码并执行该代码的任何应用程序都必须将安全性作为一个首要问题。 因此,我将探讨如何确保自动更新应用程序的安全性。

最后一个需要考虑的因素是使用应用程序自身的新版本来替换应用程序的过程。 此问题之所以引人关注,是因为它要求代码在将自身从系统中删除时能够运行。 处理这一技巧有许多种方法。

关于这些困难,最庆幸的一件事情是在 .NET Framework 与 Windows 之间,所有工具都是现成的,可以立刻用来解决这些问题。

BITS 基础知识

BITS 是 Windows 中新增的一项非常实用的文件传输功能,它通过 HTTP 异步地从远程服务器上下载文件。 BITS 可以专门利用空闲带宽来处理多个用户的多个下载任务。 尽管 BITS 不仅仅限于自动更新应用程序使用,但它是 Windows Update 使用的基础 API。 并且,由于它可用于任何应用程序,因此可用来完成创建自动更新应用程序的过程中所涉及到的大部分非常困难的工作。

下面是基本思想。 应用程序请求 BITS 处理一个或一组文件的下载。 BITS 将该任务添加到自己的队列中,并将该任务与应用程序所运行在的用户上下文关联。 只要用户登录,BITS 就会利用空闲带宽在网络中细细搜寻 (Drizzle) 这些文件。 事实上,BITS 技术的代号名称就是 Drizzle,这个词被证明是 BITS 所执行的工作的一个非常恰当的描述。

那么它到底是怎样工作的呢? 这项技术实际是一项非常复杂的技术。 首先,BITS 是作为一个 Windows 服务实现的,它维护组织成一组优先级队列的任务集合。 优先级包括前台、高、普通和低。 它按照循环法的原则,通过大约五分钟的时间片为同一优先级的每个任务分配带宽。 一旦队列中没有剩余的任务,便立即检查下一个优先级队列中的任务。

前台队列中的任务使用尽可能多的网络带宽,由于这一原因,前台优先级应只供响应用户请求的代码使用。 余下的优先级(高、普通和低)远远比前台优先级更引人关注,因为它们全都是后台优先级,也就是说,它们仅仅使用未用的网络带宽。

为了实现此后台功能,BITS 监视网络数据包,并忽略不属于它的数据包。 余下的数据包被认为是计算机带宽上的活动负载。 BITS 使用活动负载信息以及连接速度和其他某些统计信息来确定应继续下载文件还是暂停(以增加活动用户的吞吐量)。 因此,用户不会遇到带宽问题。

能够立即中断所做的工作对于 BITS 是非常重要的。 在许多情况下,BITS 不得不在仅仅下载了文件的一部分的情况下放弃与网络的连接甚至完全断开连接。 但是,下载了一部分的文件会保存起来,这样,当 BITS 抓住了与网络连接的片刻机会时,便能够从中断的位置继续下载。 这种恢复功能也有一些副作用。

请记住 BITS 是用于从 HTTP 服务器传输文件的。 要使 BITS 能够工作,服务器应与 HTTP 1.1 兼容,或者至少支持 GET 方法中的 Range 头。 这是因为 BITS 需要能够请求文件的一部分。 此外,下载的内容必须是静态内容,例如,标记文件、代码文件、位图或声音。 当请求动态内容(例如,CGI、ISAPI 或 ASP.NET 产生的内容)时,包含 Range 头的 GET 请求没有意义。

当前,BITS 有两个版本: 1.0 和 1.5。 BITS 1.0 随同 Windows XP 一起提供,它具有下列功能: 可与对话框及其他 UI 元素一起使用的可中断后台文件下载、下载优先级、任务完成及出错时的可选通知以及可选的进度通知。 BITS 1.5 随同 Windows .NET Server 一起提供。 除了 BITS 1.0 中包含的功能外,1.5 版还具有可中断的后台文件上载以及使用“基本”、“摘要”、“NTLM”、“协商”(Kerberos) 或“Passport”对连接进行身份验证的功能。 BITS 1.5 还作为与 Windows 2000 及更高版本兼容的可重新发布软件提供(请参阅后台智能传输服务)。

BITS 1.0 中的全部功能对于编写自动更新应用程序已够用,但是使用 BITS 1.5 功能可以执行更复杂的任务,例如,出售更新或处理应用程序与服务器之间的交互。

BITS、COM 和托管代码

BITS API 是作为 COM 对象实现的,正因为此,所以不能编写 .NET Framework 版的 API。 幸运的是,BITS API 非常简单易用。 本文所包含的示例应用程序是使用 C# 编写的,因此为了使用 BITS API,我不得不硬着头皮使用 .NET Framework 的 COM Interop 功能。 我在这里不深入探讨运行库可调用包装 (RCW) 及相关的内容,而仅仅说明我使用此 API 所遵循的过程。

如果我使用的是 C++,那么我的 BITS 代码的开头部分可能如下所示:

IBackgroundCopyManager* pBCM = NULL;

hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,

CLSCTX_LOCAL_SERVER, __uuidof(IBackgroundCopyManager),

(void**) &pBCM);

if (SUCCEEDED(hr)) {

// Party-on with the pBCM interface pointer

}

等效的 C# 代码使用 new 关键字创建 BackgroundCopyManager 对象,然后通过转换获得对 IBackgroundCopyManager 接口的引用,而不是通过调用像 CoCreateInstance 或 QueryInterface 这样的方法。 下面的代码片段是 C# 示例,它的作用是获取 IBackgroundCopyManager 接口:

IBackgroundCopyManager bcm = null;

// Create BITS object

bcm = (IBackgroundCopyManager)new BackgroundCopyManager();

此代码的简单性有一点误导的作用,因为需要做更多的工作来分别将托管的 BackgroundCopyManager 和 IBackgroundCopyManager 类型与底层的 COM 对象和接口关联。 .NET Framework 通过 RCW 来处理与 COM 对象的交互。 要将托管类型与 RCW 关联,必须使用属性。 图 1 中的代码说明了如何声明 BackgroundCopyManager 类和 IBackgroundCopyManager 接口,以使它们表示 BITS COM 对象。

图 1 中的代码有很多的属性(ComImportAttribute、GuidAttribute、MarshalAsAttribute 等等),这使真正的代码看起来不明显。 事实上,没有真正的代码。 接口和类的定义实际上仅仅是元数据形式的封送占位符,公共语言运行库 (CLR) 用它来直接调用 BITS COM API。

代码示例(请见本文顶部的链接)所包含的 InteropBits.cs 文件提供了与 BITS API 一起使用的所有接口、枚举类型及结构的 C# Interop 代码。 尽管示例仅仅使用了几个方法,但是我提供了完整的实现,因为它有助于您探索此 API 的更多功能。 值得注意的一点是,InteropBits.cs 文件中的代码不是托管 API,而是 COM API 实现之上的 Interop API。 Microsoft 终有一天会发布通过与 .NET Framework 类库的其余部分一致的方法向 .NET Framework 代码公开 BITS 功能的 API。

图 1 中的代码以及 InteropBits.cs 示例文件中的完整实现是手动创建的。 .NET Framework SDK 自带一个名为 TlbImp.exe 的工具。如果您有一个描述所针对的 COM API 的 TLB 文件,可以使用此工具创建类似的代码,并将其编译为托管程序集。 BITS API 不自带 TLB 文件,但是,Platform SDK 中包含一个名为 Bits.idl 的接口定义文件,该文件

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有