对于DLL不是不能,而是不想
2012-11-01 18:31
162 查看
Windows 实际上可通过重命名原始文件,然后将新文件复制到位来替换正在使用的 DLL。但在 Windows 世界中最好不要这么做。为什么呢?
即使替换了正在使用的文件,系统中仍会存在想要使用旧版本的代码。例如,假定您有两个相互配合使用的文件 A.DLL 和 B.DLL,您发出了一个可以更新这两个文件的修补程序,但此时正在使用 A.DLL。没关系,只需同时替换这两个文件。结果是,使用 A.DLL 的程序仍使用旧版本,而新程序则使用新版本。但所有程序都使用新版本的 B.DLL。
正在使用旧版本 A.DLL 的程序现在决定调用函数。它通常期望调用旧版本的 B.DLL,但却获取了新版本。此调用的成功或失败取决于您对 B.DLL 所做的更改。这两个 DLL 都假定其合作伙伴来自同一个匹配集。
即使您现在只更新没有依赖关系的单个 DLL,潜在问题仍将存在,因为 DLL 必须与其 以前的版本进行互操作。 假定您替换了正在使用的 ole32.dll。那么新启动的程序将调用新版本的 ole32.dll 并启动拖放操作。用户会将对象拖动到更新前启动的其中一个程序所创建的窗口中。您现在可以使用新版本的 ole32.dll 将消息发送给旧版本的 ole32.dll。
当您编写进程之间的通信代码时,您通常期望各个进程运行同一版本的代码,因为通信通道中的这两个端点必须针对其通信方式达成共识!“我要将消息 5(即要求文本)发送给您”并期望您将消息 12(即“这就是您要求的文本”)作为回复发送给我。如果这两端运行的代码不是同一版本,通信机制可能会不同,也许只存在细微的差别,但事实上仍会导致不兼容的情况。
假设您将一个字段添加到某个结构,而该结构正好用作消息 5 的一部分。很好。现在您有两个互不兼容的消息 5 版本 — 其中一个版本使用旧结构,另一个使用新结构。如果通信双方对于结构没有达成共识,消息 5 就无法正常工作。 如果您要并行运行旧版本和新版本,必须创建一个新消息(假定为消息 52),然后使新版本的 DLL 同时支持消息 5 和消息 52。但必须首先指出在另一端运行的 DLL 的版本并将相应的消息发送给它。
即使您尚未对结构本身进行更改,也可能您已更改了结构中某些字段的意义。如果该结构有一个枚举,且新版本将新值添加到该枚举,则新旧版本之间仍然不兼容。 当然,您可以尝试每发出一个修补程序就对新消息进行定义,然后编写代码以支持新旧版本在窗口中的两个相互冲突的版本 DLL 同时运行期间的互操作性。但是这样一来,不实用的消息集就会越来越多,当您发到第三个修补程序时,就已经拥有四个不同的消息集了(其中一个针对原始版,另一个则是针对每个修补程序)。 即使您要求这些修补程序必须按顺序进行安装,也不会为您节省任何精力;因为只要您允许运行原始程序,就必须继续与它维持互操作性。 然后就有人开始写文章抱怨您是个白痴,因为您发出修补程序的速度实在太慢了! 所以,Windows 并不是不想面对替换正在使用的文件后必须重新启动的麻烦,而是不想面对因为不执行重新启动所带来的麻烦。工程就是一组权衡。您是否愿意花费精力支持旧版本,只为获得一种连推荐的稳定状态配置都算不上的环境?
即使替换了正在使用的文件,系统中仍会存在想要使用旧版本的代码。例如,假定您有两个相互配合使用的文件 A.DLL 和 B.DLL,您发出了一个可以更新这两个文件的修补程序,但此时正在使用 A.DLL。没关系,只需同时替换这两个文件。结果是,使用 A.DLL 的程序仍使用旧版本,而新程序则使用新版本。但所有程序都使用新版本的 B.DLL。
正在使用旧版本 A.DLL 的程序现在决定调用函数。它通常期望调用旧版本的 B.DLL,但却获取了新版本。此调用的成功或失败取决于您对 B.DLL 所做的更改。这两个 DLL 都假定其合作伙伴来自同一个匹配集。
即使您现在只更新没有依赖关系的单个 DLL,潜在问题仍将存在,因为 DLL 必须与其 以前的版本进行互操作。 假定您替换了正在使用的 ole32.dll。那么新启动的程序将调用新版本的 ole32.dll 并启动拖放操作。用户会将对象拖动到更新前启动的其中一个程序所创建的窗口中。您现在可以使用新版本的 ole32.dll 将消息发送给旧版本的 ole32.dll。
当您编写进程之间的通信代码时,您通常期望各个进程运行同一版本的代码,因为通信通道中的这两个端点必须针对其通信方式达成共识!“我要将消息 5(即要求文本)发送给您”并期望您将消息 12(即“这就是您要求的文本”)作为回复发送给我。如果这两端运行的代码不是同一版本,通信机制可能会不同,也许只存在细微的差别,但事实上仍会导致不兼容的情况。
假设您将一个字段添加到某个结构,而该结构正好用作消息 5 的一部分。很好。现在您有两个互不兼容的消息 5 版本 — 其中一个版本使用旧结构,另一个使用新结构。如果通信双方对于结构没有达成共识,消息 5 就无法正常工作。 如果您要并行运行旧版本和新版本,必须创建一个新消息(假定为消息 52),然后使新版本的 DLL 同时支持消息 5 和消息 52。但必须首先指出在另一端运行的 DLL 的版本并将相应的消息发送给它。
即使您尚未对结构本身进行更改,也可能您已更改了结构中某些字段的意义。如果该结构有一个枚举,且新版本将新值添加到该枚举,则新旧版本之间仍然不兼容。 当然,您可以尝试每发出一个修补程序就对新消息进行定义,然后编写代码以支持新旧版本在窗口中的两个相互冲突的版本 DLL 同时运行期间的互操作性。但是这样一来,不实用的消息集就会越来越多,当您发到第三个修补程序时,就已经拥有四个不同的消息集了(其中一个针对原始版,另一个则是针对每个修补程序)。 即使您要求这些修补程序必须按顺序进行安装,也不会为您节省任何精力;因为只要您允许运行原始程序,就必须继续与它维持互操作性。 然后就有人开始写文章抱怨您是个白痴,因为您发出修补程序的速度实在太慢了! 所以,Windows 并不是不想面对替换正在使用的文件后必须重新启动的麻烦,而是不想面对因为不执行重新启动所带来的麻烦。工程就是一组权衡。您是否愿意花费精力支持旧版本,只为获得一种连推荐的稳定状态配置都算不上的环境?
相关文章推荐
- 罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原因
- 好的架构,并不是说能解决所有的问题,而是很清楚自己能做什么,不能做什么
- resharper安装后,F12不能转到定义,也不是反编译,而是转到对象浏览器(object browser)
- ISAM不能建立的问题不一定是什么dll文件没注册,而是网上代码太垃圾
- ISAM不能建立的问题不一定是什么dll文件没注册,而是网上代码太垃圾
- 不是你不能,而是你对自己的要求太低
- vue.js为什么不能new两次?不是不能new两次,而是第一次new之后,{{}}已经没有了, 第二次vue的时候,识别不到{{}}了,所以第二次的参数没办法替换了,给人的感觉好像是第二次new不起
- 锚定梦想,一切变简单(不是真的有勇气,而是不能帮助实现梦想的环境要坚决放弃)
- 限制一个帐户不能同时登陆。(针对于不是同一台计算机)
- 不是因为项目让你不能发光,而是因为你才让项目不能发光
- 对于一只远足的骆驼而言,可怕的并不是眼中尽是沙漠,而是心中没有绿洲...
- oracle的在sql语句后加for update 不是都起作用的,对于单表是可以的,但是对于多表关联(无论left join还是内连接等)都不能修改
- C#调用c++的DLL出现“不能直接添加引用,提示不是COM和程序集DLL”
- 一个合作良好的团队里,对于团队成员来说重要的不是垄断技术,而是分享技术的同时做到比其他成员的技术好,做领跑者,而不是垄断者。
- ApplePay对于苹果来说不是一项业务,而是一种服务。
- 当您更改为一个值该值不是有效的启动参数对于群集实例的 SQL Server 2000 或 SQL Server 2005 的 SQL Server 服务不能启动
- [转载] - 所谓踏实,并不是踏踏实实追求你的目标,而是踏踏实实把你够得着看得见的就在身边的东西干好
- 企业安全培训不是鸡肋,不能弃之
- mysql按照每天分组查询数据结果排序不是从1到31而是1后接10
- 幽默的根源不是快乐而是悲哀