【问题标题】:How to roll out a new Version of an ActiveX Control written in VB6如何推出用 VB6 编写的 ActiveX 控件的新版本
【发布时间】:2013-04-16 09:48:08
【问题描述】:

我必须维护一个用 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 然后加载页面时,它才会打印出新版本。

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

【问题讨论】:

  • 你能把HKEY_CLASSES_ROOT\CLSID\{&lt;clsid&gt;}的内容连同所有的子键和值一起贴出来吗?
  • 你能把.INF文件的内容也贴出来吗(应该在.CAB里面)?
  • 是不是因为你需要把你的哈希#改成问号?

标签: windows internet-explorer vb6 activex


【解决方案1】:

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

场景 1:错误的 .INF 文件

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

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

我能想到的另一种情况是,您正在用于构建新版本控件的同一台机器上进行测试。在这种情况下,您的控件可以由构建过程注册。在这里有助于理解how does COM activation work anyway? 尽管在构建服务器之外的机器上进行测试总是一个好主意。

可能性1:在HCKR\CLSID\{clsid}注册表键下创建AppID命名值

根据KB167597

在伪代码中,下面是为 &lt;OBJECT&gt; 标签控制组件下载的方式:

   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

上述顺序有几个例外。如果一个 AppID 在 CLSID 下找到 key,组件通常注册到 通过 DCOM 运行并且不更新。此外,一个已安装的版本密钥 优先于文件版本。这用于 Java 类 和非 PE(可移植可执行)文件。

要确认这个想法,请检查您用于测试的机器上的组件是否有AppID 注册表值。您的用户很可能不会在他们的机器上为CLSID 设置AppID。当然,除非您的组件至少在另一种不同的场景中使用。 Larry Osterman 有一篇博文 When do you need an APPID in your COM registration? 如果您不确定 AppID 是什么,请查看 this MSDN blog post

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

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

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


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

【讨论】:

  • 很遗憾,没有,开发机器与用户和测试服务器/机器完全断开连接。
  • 在哪里可以找到这个 AppId?进程监视器并没有真正的帮助,我真的不知道在那里寻找什么,因为当我打开测试页面时,IE 会执行数千次操作。
  • 好吧,现在真的很奇怪...这两个 CLSID 都没有在 HKEY_CLASSES_ROOT\CLSID 中注册
  • @FlorianPeschka 这很奇怪。如果没有别的,HKCR\CLSID\{clsid} 键必须在您加载带有控件的网页并让 IE 安装它时创建。您的 .cab 文件中必须有 .inf 文件。它有[AddToRegistry] 部分吗?你如何生成 .cab 文件?坦率地说,我从来没有使用过打包和部署向导以外的任何东西。
  • @FlorianPeschka 好的,我可以想到另一种可能性并更新了我的帖子。但。我认为如果没有相应的 HKCR\CLSID\{clsid} 键,您的组件将无法工作。
【解决方案2】:

最好只是破坏兼容性。

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

【讨论】:

  • 我这样做了——所以我现在有了一个新的 CLSID,但是 IE(在 Windows XP 上)不再安装它。有没有办法手动安装 OCX?
  • @FlorianPeschka:安装旧版本的方式相同。您可以使用 regsvr32.exe。
  • 好吧,我从来没有安装过旧的。那已经存在了大约10年,从未改变过。所以现在,没有人知道它是如何安装的。它似乎在 Windows 7 机器上自动运行,他们把它放在“Downloaded Files”文件夹中,但在 Windows XP 中不会发生这种情况
  • @C-PoundGuru 注册组件是 IE 的工作。这种部署方案的重点是让用户免于运行任何安装程序。
猜你喜欢
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
相关资源
最近更新 更多