当您从机器上删除现有版本后,IE 会成功下载并安装组件,这完全是关于版本控制的。在这一点上,我可以想到几种情况。
场景 1:错误的 .INF 文件
打开您的 .CAB 文件。您将在里面看到 .INF 文件。打开此 .INF 文件并找到 [<component name>.ocx] 部分。检查FileVersion=...的值,应该是FileVersion=1,0,0,80。我发现如果您通过之前由打包和部署向导生成的 .BAT 脚本更新现有的 .CAB 文件,则此值不会自动更新。
场景二:测试环境被构建过程污染
我能想到的另一种情况是,您正在用于构建新版本控件的同一台机器上进行测试。在这种情况下,您的控件可以由构建过程注册。在这里有助于理解how does COM activation work anyway? 尽管在构建服务器之外的机器上进行测试总是一个好主意。
可能性1:在HCKR\CLSID\{clsid}注册表键下创建AppID命名值
根据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
上述顺序有几个例外。如果一个 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\{<clsid>} 项下的值。查找AppId 类型为REG_SZ 的命名值。
可能性 2:构建过程更改了 HCKR\CLSID\{clsid}\InprocServer32 注册表项的默认值
检查 HCKR\CLSID\{clsid}\InprocServer32 注册表项的默认值 ((Default))。如果它指向您用作组件编译过程输出的位置,那么它很可能是在构建期间设置的(除非您将构建结果直接放到C:\WINDOWS\Downloaded Program Files,我真的很怀疑)。操作系统使用此值来确定在 COM 组件激活时使用什么二进制文件。运行 regsvr32 /u <path to the .ocx created during compilation> 并使用网页重新运行测试。
如果没有任何帮助,您需要更仔细地调查问题。启动Process Monitor,要求它跟踪 IE 进程的注册表和文件系统活动,并查看 IE 如何决定(不)更新您的控件。收集的跟踪信息中的有趣信息应该在您的控件的CLSID 的注册表查询之后立即开始。