6

我必须维护一个用 VB6 编写的旧的活动 x 控件。

当我们为其开发了一些新功能时,我现在需要向用户推出这个新版本。如何以最不显眼的方式做到这一点?

控件是这样嵌入的

<OBJECT classid="clsid:..." CODEBASE="activex/plugin/myOCX.CAB#version=1,0,0,42">
    <PARAM name="RunOnLoad" value="true"></PARAM>
    [...]
</OBJECT>

不,当我将 更改#version为实际的 ( 1,0,0,80) 时,它不会改变任何内容。IE 仍然加载旧版本(我可以通过一个提醒 OCX 版本的功能来检查)。

只有当我从我的机器中删除 OCX 然后加载页面时,它才会打印出新版本。

显然,用户不能也不应该这样做。所以问题仍然存在:一旦将新版本部署到服务器,我如何才能有效地强制我的用户使用新版本?

4

2 回答 2

1

当您从机器中删除现有版本后,IE 会成功下载并安装组件,这完全取决于版本控制。在这一点上,我可以想到几种情况。

场景 1:错误的 .INF 文件

打开您的 .CAB 文件。您将在里面看到 .INF 文件。打开此 .INF 文件并找到[<component name>.ocx]部分。检查值FileVersion=...,应该是FileVersion=1,0,0,80。我发现如果您通过打包和部署向导之前生成的 .BAT 脚本更新现有的 .CAB 文件,此值不会自动更新。

场景二:构建过程污染的测试环境

我能想到的另一种情况是,您正在用于构建新版本控件的同一台机器上进行测试。在这种情况下,您的控件可以由构建过程注册。在这里它有助于理解COM 激活是如何工作的?不过,在构建服务器以外的机器上进行测试总是一个好主意。

可能性 1:构建过程在注册表项AppID下创建了命名值HCKR\CLSID\{clsid}

根据KB167597

在伪代码中,以下是为<OBJECT>标签控制组件下载的方式:

   Check the Registry for CLSID
   If CLSID of OBJECT is NOT found in the registry
      Download OBJECT
   Else If no #Version specified in CODEBASE tag
      Use OBJECT installed on system
   Else
      Check InprocServer32 key for location of installed component
      If File version of installed component < CODEBASE #Version Tag
         Download OBJECT

上述序列有几个例外。如果在 CLSID 下找到 AppID 键,则该组件通常注册为通过 DCOM 运行并且不会更新。此外,Installed Version 密钥优先于文件版本。这用于 Java 类和非 PE(可移植可执行)文件。

AppID要确认这个想法,请检查您用于测试的机器上的组件是否存在注册表值。您的用户很可能不会在他们的机器上AppID设置。CLSID当然,除非您的组件至少在另一种不同的场景中使用。Larry Osterman 有一篇博客文章您何时需要在 COM 注册中使用 APPID?如果您不确定是什么,还请查看此 MSDN 博客文章AppID

如何确定是否AppID设置为 a CLSID?打开注册表编辑器regedt32,并检查HKEY_CLASSES_ROOT\CLSID\{<clsid>}键下的值。查找AppId类型的命名值REG_SZ

可能性 2HCKR\CLSID\{clsid}\InprocServer32 :构建过程更改了注册表项的默认值

检查注册表项的默认值 ( (Default)) 。HCKR\CLSID\{clsid}\InprocServer32如果它指向您用作组件编译过程输出的位置,那么它很可能是在构建期间设置的(除非您将构建结果直接放在C:\WINDOWS\Downloaded Program Files我真的怀疑的地方)。操作系统使用此值来确定在 COM 组件激活时使用什么二进制文件。使用网页运行regsvr32 /u <path to the .ocx created during compilation>并重新运行测试。


如果没有任何帮助,您需要更仔细地调查该问题。启动Process Monitor,要求它跟踪 IE 进程的注册表和文件系统活动,并查看 IE 如何决定(不)更新您的控件。收集的跟踪中的有趣信息应该在您的控件的注册表查询之后立即开始CLSID

于 2013-04-16T13:13:26.903 回答
0

最好只是破坏兼容性。

打开Project Properties并从Component选项卡中更改Version CompatibilityNo Compatibility. 编译,然后更改您的clsid以匹配新的。

于 2013-04-16T12:54:11.170 回答