用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心编程技巧C++ Builder

实现应用程序中的并行组件共享(1)

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-03-16 20:41:14

摘要:探讨 Microsoft(R) Windows(R) 2000 和 Windows 98 第二版本中并行共享组件的实现(如 Windows 认证规范中讨论的)。包括新的并行组件的创建以及使用 DLL/COM 重定向处理相同组件的不同版本之间的不兼容性。包括编写和安装并行组件以及重新打包和测试应用程序的指南。

目录
介绍
一点背景知识
新组件共享策略
比较两种策略
创建新的并行组件
并行组件编写指南
安装并行组件
DLL/COM 重定向
使用 DLL/COM 重定向

介绍
现代操作系统和应用程序由许多组件构成。组件是自包含的软件实体,该软件实体提供了一组可被各种应用程序广泛使用的函数。因为单独的组件被多个应用程序使用,所以组件的共享是很有必要的。

成功的全局组件共享要求任何共享的组件功能和该组件的先前版本完全一样。但是如果不能实现的话,要达到百分之百的向后兼容实际上是很难的,因为测试所有使用共享组件的配置是非常困难的。新旧应用程序最终都使用相同的组件,因此,随着时间的推移,修正并改进这些组件变得愈加困难。

同时,组件的实际功能也不太容易定义。应用程序可能成为依附在组件上的意外副作用,而不被认为是该组件核心功能一部分。例如,组件中的一个错误可能影响到应用程序,以及当组件开发者选择修正此错误时应用程序失败,这种情况就是人们常说的“DLL Hell(该死的 DLL)”。这使得那些使用组件的应用程序会更加深该问题的严重性。

这种缺乏向后兼容性的情况使得在部署新的应用程序时,必须中断已部署的应用程序,或是牺牲某些新应用程序的功能。所有新的应用程序都要求共享组件的版本与已配置的版本不同。要在增强应用程序稳定性的同时提供成功的共享,Microsoft 已在 Windows 2000 和 Windows 98 第二版本中引入了并行共享,开创了通过选择性隔离来共享组件的新方式。

一点背景知识
在了解并行共享的详细信息之前,让我们看一些背景资料以及“DLL Hell”的问题。

组件共享
Windows 最初就采纳了共享的概念。所有操作系统都在提供稳定性、完整的服务集的需求与操作系统所要求的硬件的资源限制的之间寻求平衡。到目前为止, CPU 用量和磁盘空间仍然是 PC 平台中非常紧张的资源。很显然,要将操作系统和应用程序代码装入到一个很小空间,必须尽可能地共享代码。与许多其他好处相比,代码共享加强了硬件资源的均衡运用,并且最大程度地减少在前期质量保证检测中暴露的问题。代码共享是使 Windows 成功的要素之一。

Windows 的共享并不限于代码。应用程序和组件的状态,可以用注册表状态的形式、文件系统中的应用程序专用数据存储的形式和公开全局命名空间的 Windows API 的形式,在整个操作系统中找到。这类共享,在多个软件供应商生产的应用程序之间提供了高级别的互操作性,降低了成本,提高了软件的效率。

但是,共享也必须付出一些代价。共享意味着应用程序彼此依赖,引入了脆弱性因素。更改某一组件会对其他组件产生无法预料的影响。典型的情况,一个应用程序可能依赖于共享组件的一个特定版本。而另一个应用程序可能是用该共享组件的升级(或降级)版本安装的,因此第一个应用程序可能受此更改的影响。在极端的情况下,曾经工作正常的应用程序会突然功能紊乱,甚至失败。这种情况通常称为“DLL Hell”。

隔离
在系统中,共享的反面是隔离。通过将所有资源和代码静态地绑定到应用程序,可以隔离应用程序。但是如今对于依赖于 COM 或其他全局存储的系统资源的应用程序来说,完全的隔离是不可行的。

减少应用程序脆弱性的一种解决办法是,有选择地隔离应用程序和组件。在这种方案中,所有应用程序可能都具有对相同组件的访问权,但该组件目前有多个版本可用。组件开发者有权编制旧组件的新版本、作一些改进或修正错误。而客户可以选择适合于特定应用程序的版本。就像走进一个汽车配件商店为您的 1984 Chevy 挑选一个燃油泵一样。您会发现货架上的这个泵和一些比它晚来的适用于其他车型的泵并行放在一起。在使用组件的情况下,关键是提供适合于每个应用程序的版本并且隔离其他不同的版本。而且,在重定向的情况下,应用程序可以进行配置,以使用适合于该特定应用程序的组件版本,而不管最近开发的或以后将要开发那些版本。

并行共享
为鼓励这类隔离,Microsoft Windows 2000 和 Windows 98 第二版本的新的组件共享形式叫做并行共享,它使用选择性隔离最大程度地减少 DLL Hell。并行共享允许相同组件(COM 或 Win32)的多个版本同时在不同的进程中运行。因此,应用程序可以使用设计并测试过的组件的特定版本,而不管另一个应用程序要求该相同组件的不同版本。这种安排允许开发者建立并部署更可靠的应用程序,因为开发者能指定他们的应用程序使用的组件版本,和系统中其他应用程序无关。

新组件共享策略
Windows 2000 和 Windows 98 第二版本中的并行共享遵照以下两种策略:

创建并行组件。开发者构造一些新组件,它们支持该组件多个版本的同时执行。这些新组件的用户现在能够使用已建立并安装的版本,不管在计算机中安装了哪些其他版本。


DLL/COM 重定向。开发者和管理员重新包装现有的应用程序和组件,使要求的共享组件版本专门用于需要它们的应用程序,各自与其他版本并行使用。
并行组件,不论是最近创建的还是现有的、或重新配置的应用程序的一部分,并不是所有的方案都支持。

创建并行组件的情形主要发生在当在另一个容器应用程序的内部被主持的过程中。例如,如果您的控件将要由桌面 Windows 应用程序(用 Microsoft Visual Basic(R) 或 Visual C++(R) 语言编写)使用,那么这些控件最好使用并行设计。不推荐在服务器中使用并行组件。


DLL/COM 重定向的情形主要发生在,新的客户端应用程序正在部署到已经支持几个其他应用程序的计算机上时,或者正在部署新的客户端应用程序的地方,要求它对由于其他应用程序的安装所引起的共享组件的更改有更大适应力。不推荐在服务器中使用 DLL/COM 重定向。
注意   DLL/COM 重定向致力于解决部署现有应用程序和组件时的应用程序冲突。在开发新的应用程序或组件时,最佳策略是部署被天然隔离的并行组件。

比较两种策略
下表比较两种方法,DLL/COM 重定向和创建并行 (SxS) 组件,并指导如何为您的方案选择正确的方法。

表 1. 并行策略比较

属性 SxS 组件 DLL/COM 重定向
主要焦点是什么? 建立稳定的新组件,使它在以后版本中将免受造成组件“向后不兼容”的更改的影响。 将现有应用程序与由于其他应用程序安装了不兼容的共享 DLL 而导致的问题隔离开。
指定的版本对于使用它们的应用程序来说是隔离的吗? 是。SxS 组件总是应当部署成:对于使用它们的应用程序来说是隔离的。 是。使用 DLL/COM 重定向的应用程序使用安装在该应用程序目录中的共享组件的版本,不管在系统中安装了哪些其他版本。
需要新代码还是对现有代码进行修改? 是。建立 SxS 组件(或编写现有组件 SxS)至少需要将 COM 注册代码更改为允许按相对路径进行访问。可能需要一些附加编码更改,以确保在 SxS 运行版本之间正确地处理全局状态。 否。DLL/COM 重定向允许应用程序重新配置为,不需要更改任何代码或重新编译便能安装并运行 SxS。这允许没有应用程序源代码访问权的管理员便能重新配置它以解决 DLL Hell 问题。
该策略在所有方案中均采用吗? 是。SxS 组件被设计并编码以安装并运行 SxS。因此,经过良好设计、开发和测试的 SxS 组件(以及使用它们的应用程序)将不会有与 DLL Hell 相关的问题。 否。DLL/COM 重定向不要求改变代码。现有的应用程序和组件可能没有按同时运行多个版本的要求进行设计。经验表明在大多数情况下现有的应用程序和组件可以运行 SxS,但需要进行测试才能确认对于特定方案是否是这样。(请参见 选择要隔离的组件。)


一般的常规处理方法:

如果 DLL Hell 问题影响到现有应用程序的部署,可使用 DLL/COM 重定向隔离冲突的组件(要进一步了解该选项,请参见下面的方案)。


如果正在建立新的应用程序,并且要针对 DLL Hell 问题进行设计和部署,则开发并行组件。
创建新的并行组件
并行共享,要求开发者在创建新的应用程序时编写并行组件。它们都是普通的 COM 或 Win32 组件,不过它们安装在应用程序目录(或其子目录)中,而不是系统目录中。它们是与特定应用程序隔离的,并且不被所有应用程序全局共享。

因此,组件可以安全地与安装在其它地方的同一组件的不同版本,并行安装在另一个应用程序目录中。如果系统中的另一个应用程序要求(因此安装了)不同的版本,您的应用程序不会受到影响。这两个应用程序将和它们各自的组件版本一起运行。

如果另一个应用程序在系统中安装了新的组件版本,您的该组件版本将保持不变,因为您已将它安装到自己的应用程序目录中。在其他应用程序使用它的版本的同时,您的应用程序继续使用随该应用程序提供的组件版本。操作系统可以同时加载这两个版本。

同样,因为并行组件对于安装它的应用程序是“私有”的,所以应用程序的卸装程序始终可以安全地删除并行组件,按照定义,任何其他应用程序都不能依赖于私有组件。

注意   并行组件必须通过操作系统正确注册(在本章后面部分中说明),组件的每个版本才不会与该组件的其他现有版本冲突。

注意   Windows 2000 和 Windows 98 第二版本均支持并行共享。以前的 Windows 操作系统不支持它;但是,在这些系统中,可以在系统目录中安装一个并行 DLL(按照下一节中的指南编写的 DLL)。因此,DLL 以全局共享(向后兼容)方式工作。应用程序必须动态地检查操作系统版本以确定要使用的共享方法。

并行组件编写指南
下面的指南概述了在产生并行组件(COM 或 Win32)中涉及的事项。当您编写这类组件并将它们放在应用程序目录中时,您的代码被私有化为该应用程序的上下文。当您将数据放入以该应用程序名称为根项的注册表项中时,该数据被私有化为该应用程序的。

您的并行组件的用户,与您的组件的其他用户所需要的更改绝缘。您还能够更新您的组件,而不必担心破坏现有的应用程序。应用程序能够安装您的组件而不用重新引导,即使另一个应用程序正在使用该组件的不同版本。

注意   这些指南是当前 Windows 认证指南的更稳定的形式,它告诉用户将 Win32 DLL 放在应用程序的目录中。

一般事项
不要尝试替换受“系统文件保护”(随 Windows 2000 提供)所保护的任何文件,包括大部分 .sys、.dll、.exe 以及 .ocx 文件。


必须测试所有组件以确保并行的有效性,尤其在可能出现共享的区域中,因为没有任何由当前操作系统强制的并行。


将所有版本特定名称一起收集到 #defines 中,以便于将源代码从一个版本迁移到另一个版本。执行此操作允许用户在某个位置更改版本;然后自动更改所有注册表项。例如:
#define MyRegistryKey "MyAppv1.0.0.0"

发行组件的新版本时,只需要在某个位置更改该版本。

谨防丧失对组件进行快速修正的能力,因为它们正在随意定位的应用程序目录中。作为组件开发者,您可能不知道所有需要修正组件的位置。应用程序供应商需要向用户分发更新。


谨防由于疏忽所造成的交叉进程共享。例如,共享的内存部分可能导致问题,因为该部分内存不能在组件的不同版本之间交叉共享。


需要将所有共享的数据结构设计成并行(对于组件的每个版本有所不同),包括内存映射的文件、互斥程序、命名管道以及硬件驱动程序。


必须将不是长期保存的数据存储在 TEMP 目录中。


不要将用户数据放在全局位置。应用程序数据和用户数据应该明确分开。
增强您的组件
在安装和卸装由不同供应商提供的组件过程中,必须正确引用全局注册表中 GUID 的计数。在 GUID 注册表项下维护一个引用计数是执行该操作最可靠的方法。
HKEY_CLASSES_ROOTCLSID{GUID}InprocServer32
Default=foo.dll
ThreadingModel=Apartment
RefCount=1

注意   必须引用与 GUID 无关的 DLL 计数。

不要注册 COM 注册表的完整路径名,可以依靠应用程序目录的目录搜索查找您的组件及其从属。


如果更改了 COM GUID 下的元数据(如线程模型),则需要为组件更名,并应用新的 GUID,因为它是组件的有效新版本。需要执行此操作是因为注册表中的数据在另一个应用程序的上下文中(具有该应用程序私有的组件版本)可能无效。


在您的 DLL 中,而不是在单独的文件中,必须包含类型库。


不要使用 LoadRegTypeLib ,通过注册表加载类型库。注册表中类型库的注册表项是全局状态,并且以私有规则运行计数器。因此请使用 LoadType Lib。


OLEAUT 创建外部类型库新版本的能力是脆弱的,并且易于失败。建议不要对并行组件使用外部类型库。

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:14,546.88000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号