- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望每个人都能原谅这个问题的长度和叙述方式。我决定在我的博客中详细描述这种情况。后来我看到了乔尔对这个网站的邀请,我想我会把它贴在这里,看看是否有人对这种情况有任何了解。
我编写并现在支持一个应用程序,该应用程序包含一个 Visual Basic 胖客户端,将 DCOM 与使用 ATL 用 C++ 编写的中间层 COM+ 组件通信。它在我们所有的八个办公室中运行。每个办公室都有一个后端服务器,其中包含 COM+ 应用程序(由 18 个单独的组件组成)和 SQLServer。 SQLServer 通常位于同一后端服务器上,但并非必须如此。
我们最近将我们最大的办公室——纽约——的后端服务器从一个 MSC 集群迁移到了一个托管在 VMWare 的 ESX 技术上的新虚拟机。由于 COM+ 应用程序的位置已从旧服务器移动到具有不同名称的新服务器,因此我必须重定向所有客户端,以便它们在新服务器上激活 COM+ 应用程序。这个过程很老套,因为我对几个经历过类似基础设施升级的小型办公室做了基本相同的事情。
一切似乎都很正常,周一早上,整个办公室——大约 1,000 个 Windows XP 工作站——在新服务器上正常运行,没有发生任何事故。但是后来电话来自我的移动组——有一位在家工作的律师使用 VPN 连接,在重定向到新服务器后出现奇怪的错误:
FillTreeView2 错误 - stub 收到错误数据。
嗯?我以前从未见过此错误消息。是新服务器吗?但是办公室里的所有工作站都运行良好。我告诉移动组将代理切换回旧服务器(仍在运行),错误消失了。那么有什么不同呢?原来这位律师正在家里运行 Vista。
我们不在我们的任何办公室运行 Vista,但我们确实有一些律师在家里运行 Vista(当然有些在我的纽约办公室)。我也是这样,我从来没有见过这个问题。为了确认存在问题,我启动了我的 Vista 笔记本电脑,将其指向新服务器,并得到了同样的错误。我把它指向旧服务器,它运行良好。很明显,Vista 和新服务器上的组件存在一些问题——这个问题似乎不会影响 XP 客户端。会是什么呢?
下一站——我的笔记本电脑上的应用程序错误日志。这产生了有关错误的更多信息:
来源:Microsoft-Windows-RPC-Events
日期:2008 年 9 月 2 日上午 11:56:07
事件 ID:10
级别:错误
电脑:DevLaptop
说明:应用程序无法完成 COM 调用,因为错误
接口(interface) ID 作为参数传递。
预期的接口(interface) ID 是 00000555-0000-0010-8000-00aa006d2ea4,
返回的接口(interface) ID 为 00000556-0000-0010-8000-00aa006d2ea4。
用户操作 - 联系应用程序供应商以获取应用程序的更新版本。
界面 ID 提供了我需要解开谜团的线索。 “预期”接口(interface) ID 标识 MDAC 的 Recordset 接口(interface)——特别是该接口(interface)的 2.1 版。 “返回的”接口(interface)对应于更高版本的 Recordset(2.5 版与 2.1 版的不同之处在于在 vtable 的末尾包含了一个额外的条目——方法 Save)。
实际上,我的组件接口(interface)公开了许多将 Recordset 作为输出参数传递的方法。那么他们是否突然返回了更高版本的 Recordset —— 具有不同的接口(interface) ID?情况确实如此。然后我想,这有什么关系。 vtable 对于旧接口(interface)的客户端来说看起来是一样的。事实上,我怀疑如果我们谈论的是进程内 COM 而不是 DCOM,这种明显无害的阻抗失配会被默默忽略,不会引起任何问题。
当然,当进程和机器边界开始发挥作用时,客户端和服务器之间有一个代理和一个 stub 。在这种情况下,我使用了带有自由线程编码器的类型库编码。所以有两个谜团需要解开:
为什么我在新服务器上的方法的输出参数中返回不同的接口(interface)?
为什么这仅影响 Vista 客户端?
由于我的服务器软件托管在我的八个办公室中的每一个的服务器上,我决定尝试将我的 Vista 客户端依次指向所有这些,以查看哪些与 Vista 有问题,哪些没有。照明测试。一些较旧的服务器仍然可以与 Vista 配合使用,但较新的服务器则不能。尽管一些较旧的服务器仍在运行 Windows 2000,而较新的服务器已在 2003 年运行,但这似乎不是问题。
在比较组件 DLL 的日期后,似乎只要客户端指向具有 2003 Vista 之前的组件 DLL 的服务器就可以了。但是那些具有 2003 年之后日期的 DLL 是有问题的。信不信由你,多年来服务器组件上的代码没有(或至少没有显着的)变化。显然,不同的日期仅仅是由于在我的开发机器上重新编译了我的组件。似乎其中一次重新编译发生在 2003 年。
灯泡继续亮着。当将记录集从服务器传回客户端时,我的 ATL C++ 组件将该接口(interface)称为 _Recordset。此符号来自嵌入在 msado15.dll 中的类型库。这是我在 C++ 代码中的一行:
#import "c:\Program Files\Common Files\System\ADO\msado15.dll"no_namespace rename ( "EOF", "adoEOF")
不要被msdad15.dll中的15所欺骗。显然这个 DLL 在 MDAC 版本的长系列中没有改变名称。
当年编译应用程序时,MDAC的版本是2.1。所以 _Recordset 用 2.1 接口(interface) id 编译,这是运行这些组件的服务器返回的接口(interface)。
所有客户端都使用 1999 年生成(我相信)的 COM+ 应用程序代理。定义我的接口(interface)的类型库包括以下行:
importlib("msado21.tlb");
这解释了为什么他们期望在我的方法的输出参数中使用 Recordset 2.1 版。显然,问题出在我 2003 年的重新编译以及当时 _Recordset 符号不再对应于 2.1 版的事实。事实上,_Recordset 对应于 2.5 版本,具有独特的接口(interface) id。我的解决方案是在我的 C++ 代码中将所有引用从 _Recordset 更改为 Recordset21。我重建了组件并将它们部署到新服务器。瞧——客户似乎又高兴了。
总之,我还有两个烦人的问题。
为什么代理/ stub 基础结构与 Vista 客户端的行为似乎不同?与 XP 相比,Vista 似乎对从方法参数返回的接口(interface) ID 进行了更严格的检查。
我应该如何在 1999 年以不同的方式对此进行编码,以免发生这种情况?接口(interface)应该是不可变的,当我在较新版本的 MDAC 下重新编译时,我无意中更改了我的接口(interface),因为这些方法现在返回不同的 Recordset 接口(interface)作为输出参数。据我所知,当时的类型库没有特定于版本的符号——也就是说,更高版本的 MDAC 类型库定义了 Recordset21,但该符号在 2.1 类型库中不可用。
最佳答案
当 Microsoft 获得安全信仰时,DCOM(和底层 RPC)得到了很多关注,并且肯定会进行更改以关闭导致更严格编码(marshal)的安全漏洞。我很惊讶你在 Vista 中看到了这一点,但在 XP 中没有看到,但它可能为 Vista 添加了额外的检查。或者,XP 中的可选严格性可能在 Vista 中成为强制性的。
虽然我对 MDAC 的了解还不够多,无法知道您是否可以阻止这种情况发生,但我确实知道安全性是 Microsoft 非常愿意牺牲向后兼容性的少数几个领域之一,因此您可能什么也做不了”更好”早在 1999 年。
关于windows-vista - Vista 是否对 DCOM 调用中的接口(interface) ID 进行更严格的检查? ( stub 收到坏数据)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63720/
最近我遇到了 AngularJS Strict DI 模式。使用它的目的和好处是什么?通过在移动设备上使用它,我们会获得显着的性能提升吗? 我尝试将它应用到我的代码中,并且在编写代码时我没有做任何注释
要在复制文本的底部添加额外信息 - 我想使用以下 JS: document.addEventListener('copy', (event) => { const pagelin
Java 是否有一个好的、严格 的日期解析器?我可以访问 Joda-Time,但我还没有看到这个选项。我发现了“Is there a good date parser for Java”这个问题,虽然
在下面的网页中,图像和 div 之间有几个像素的间隙。 (我已经在 Firefox 3 和 Safari 4 中测试过。) 我怎样才能缩小差距? body { background-color:
前段时间我遇到了一个“问题”,但我一直没有弄清楚。希望有人能照亮它。当我将 DOCTYPE 从严格更改为过渡时,是什么导致某些浏览器(Chrome、Opera 和 Safari)以不同方式呈现页面。我
PHP 以其类型杂耍而闻名。我必须承认这让我很困惑,而且我很难在比较中找出基本的逻辑/基本内容。 例如:如果 $a > $b 为真且 $b > $c 为真,是否意味着 $a > $c总是也是真的吗?
有在ECMAScript Language Specification11.9.1 等于运算符 (==): NOTE 3 The equality operator is not always tra
考虑这些不同的尝试,比如 last : Prelude> import Data.Foldable Prelude Data.Foldable> foldr const undefined (reve
我正在考虑使用 jQuery 元数据插件。看起来很有趣,但是... ... alert($('li.someclass').metadata().some); 这段代码有效吗? 更新 当然这是一个老例
我有一个 CSS 文件,我的本地开发服务器(webpack)正在提供一个显然错误的 mime 类型。 Refused to apply style from 'http://localhost:100
因此对于 Google Chrome 和 Opera,cookie 具有 SameSite 属性,该属性可以具有以下两个值之一:strict 或 lax。 它们之间的一些区别之一是 SameSite=
我试图到处寻找这个问题的答案,但似乎我运气不好。 我有一个非常简单的 Mongoose 模型 var userObject = { profile: { username: {
我正在为必须使用 XHTML 1.0 Strict 进行验证的类编写程序。根据 w3 的验证程序,我的页面通过了验证。我还有一个 HTML5 版本(这是原始版本),它可以按应有的方式进行验证和工作。
我得到了很多 validation errors因为 在 里面。如果我删除 br 标签,那么它工作正常。 为什么会产生问题? 最佳答案 不是br在p里面,而是你没有结束 br与 /特点。你有 在代码中
好吧,这让我抓狂。 我想在我的文档周围加上边框。它应该很好地绕过整个窗口/视口(viewport)。所以我定义: body { border: 1px solid red; } 当我的文档处于 q
我在 MySql 服务器上运行的查询遇到问题。这是查询: SELECT itms.Gender,itms.Age, (CASE WHEN (plv.Discount = 0 OR t1.EverGre
我有以下 javascript 函数,如果所有必填字段都不完整并且是我使用 Google Apps 脚本创建的表单的一部分,它会阻止表单提交。请注意,#submitbutton 实际上是一个常规按钮,
我是一名优秀的程序员,十分优秀!