【问题标题】:Ageing 32 bit OCX control fails to load in .NET老化的 32 位 OCX 控件无法在 .NET 中加载
【发布时间】:2012-03-24 23:08:27
【问题描述】:

我正在开发一个依赖老化 OCX 控件的 .NET 应用程序。该控件提供了一个终端界面,允许用户与航空公司预订系统进行交互。它已经在几个 VB6 应用程序中“成功”使用,但未来我们需要/希望在 .NET 应用程序中使用它。

因此,在使用 .NET 4 和 Visual Studio 2010 的 Windows XP (x86) 机器上,我创建了使用已正确注册的控件的 Winforms 和 WPF 应用程序。我已经实现了 Reg Free COM 并同时使用了 XCOPY 和 Click-Once,这两个项目都可以成功部署到 Windows XP (x86) 机器上,并且都可以按预期工作,而无需注册控件。不幸的是,在 Vista (x86) 和 Windows 7 (x64) 上的部署情况并非如此,在这些环境中应用程序启动但没有呈现控制。

为了了解问题,我尝试在我的 Windows 7 (x64) 开发环境中注册该控件。我都试过了:

  • 使用普通 regsvr32(x64 注册表)注册控件
  • 使用 sysWOW64 版本的 regsvr32(x86 注册表)注册放置在 SysWOW64 目录中的控件

在这两种情况下,控件似乎都已成功注册,并且在一个全新的 Winforms 项目中,我可以将控件添加到工具箱中(出现图标等)。但是,一旦我将控件拖到窗体,它就会在窗体的角落显示为一个小框(而不是在 XP 上看到的终端窗口),甚至 Interop 文件的生成方式与 XP 相同?!

XP中的控件

选中时在 Windows 7 中看到的控件

我花了很长时间在网上搜寻任何类型的解决方案或类似问题,但无济于事。欢迎提出任何建议!

更新 1:

正如@DanielHilgarth 所建议的那样,我使用该控件在 VB6 中创建了一个基本应用程序并在 Windows 7 (x64) 上运行它,令人讨厌的是,即使是 .NET 应用程序或项目,它也会获取已注册的 COM 组件并按预期工作可以并排运行,看不到任何控件!?

更新 2

如果我使用该控件在我的 XP 机器上创建一个基本的 Winforms 应用程序(但需要注册该控件,即不是免费的)。当它在我的 Windows 7 (x64) 机器上运行时,如果没有注册控件将无法启动(如预期的那样)。控件是否在 x86/x64 注册表中注册对应用来说似乎无关紧要,无论以哪种方式启动,但看不到控件!?

更新 3

我注意到,如果我在我的 Windows 7 环境中运行 Winforms 项目(在 XP 和 COM reg 中创建),除非控件再次注册(如预期)似乎不在乎哪个注册表,否则表单设计器将失败该组件已注册。注册后,将看到表单设计器(没有控件),并且在构建时会看到以下警告:

研究这个警告是徒劳的,它似乎表明 Visual Studio 正在寻找错误的注册表路径,但我找不到解决这个问题的方法?

【问题讨论】:

  • Win7机器上的OCX控件能否成功使用VB6应用程序?顺便说一句:您可以将图像上传到 imageshack 或类似的托管服务提供商,并将它们链接到您的问题中。
  • 这听起来不像是注册问题,会产生异常。这听起来像是一个 VB6 控件,它不能托管在 .NET 表单上。并非所有方案都受支持,它必须是行为良好的 ActiveX 控件。不能无窗口,不能创建自己的顶级窗口,等等。与该控件的所有者合作以继续前进。
  • @DanielHilgarth,这是一个非常好的问题。我以前没有走这条路,因为以前的开发人员的 VB6 应用程序很差,需要他“自定义”安装它们!但我会试一试!
  • @HansPassant:如果是这样的话,它根本行不通。但它确实适用于 XP,因此它可以托管在 .NET 表单上。
  • @HansPassant - 这听起来是一个可行的建议,但如果是这种情况,该控件肯定不会在任何 .NET 项目中工作;而不仅仅是 XP 之后操作系统上的 .NET 项目?

标签: .net visual-studio-2010 com 64-bit ocx


【解决方案1】:

我认为我无法回答您的问题,但也许我可以为您提供一些疑难解答的想法。

我只是在猜测,但问题的根源可能是 64 位 Windows 上的 32 位注册问题,或者可能是因为您使用 UAC 运行而导致的权限问题。要对最后一部分进行故障排除,您可以关闭 UAC 并查看是否有帮助。

64 位 Windows 上的 32 位 COM

我觉得 32 位和 64 位有点混淆。 64 位 Windwos 上只有一个注册表。但是,COM 组件是 32 位或 64 位的。这意味着在 64 位注册表中需要有单独的区域用于 32 位注册,因此相同的注册可以有两种不同的实现(Wow6432Node)。

现在重要的部分是 32 位进程将看到注册表的修改版本不知道它。当 COM 组件注册 CLSID 时,它使用路径 HKCR\CLSID,不知道它被映射到 HKCR\Wow6432Node\CLSID。另一方面,如果您想使用 64 位 Regedit 检查 32 位注册,则需要查看那里。但是,使用%systemroot%\syswow64\regedit.exe 的 32 位 Regedit 在 64 位上解决 32 位注册问题通常更容易,您可以在其中看到 32 位进程看到的注册表。

您要使用的控件是本机 32 位控件,不会在 64 位进程中加载​​或运行。您写道您正在“使用普通 regsvr32(x64 注册表)注册控件”,但这是不可能的。您应该确保从 32 位角度正确注册了控件及其所有依赖项。如果您从 64 位的角度来看注册,您需要完全了解 Windows 如何将注册表重新映射为 32 位(或者只是切换到 32 位 Regedit)。

您显然想使用免注册 COM,但在尝试之前,您或许应该尝试看看是否可以使用“老派”注册解决您的问题。

免注册 COM

我建议阅读文章Registration-Free Activation of COM Components: A Walkthrough中的疑难解答部分:

在解决免注册 COM 问题时,事件查看器 [...] 是您的朋友

【讨论】:

  • Martin,感谢您抽出宝贵时间回复!
    在某种程度上,您对围绕 32/64 位注册表的混淆是正确的;主要源于试图调查这个问题。在很多情况下,人们建议必须使用 SysWow64 目录中的 regsvr32.exe。我试图在我的帖子中表明我使用了两个版本的 regsvr32.exe;两者似乎都成功了,事件查看器中没有详细说明任何问题,但仍然没有任何效果!....
  • ...您已经确认了我对 Wow6432Node 的理解,但我对 Visual Studio 中看到的警告仍然有些困惑。我可以注册组件;在 '32bit' regedit 中查看时,在 HKCR\Wow6432Node\CLSID 下的 'x64' regedit 以及 HKCR\CLSID 下找到该条目,但 Visual Studio 看不到这个?...
  • ...我同意首先使用注册方法,并且一直在测试各种东西。我注意到的一件奇怪的事情是我可以取消注册组件并确认注册表中没有留下任何类 ID。然而,只要组件 DLL 位于 Windows\SysWow64 目录中,VB6 测试应用程序(在已注册组件的 XP 机器上创建)就可以工作吗?
【解决方案2】:

看来问题出在 DEP(数据执行保护)上。我认为 OCX 正在做不允许的事情!?

在运行各种测试 Windows 应用程序时,或者在注册控件时没有任何异常等,仍然令人费解。

为了纠正这种情况,我根据blog 编辑了帖子构建。现在这意味着我可以调试和查看控件,当通过 ClickOnce 发布控件时,现在可以在所有操作系统(即 XP/Vista/Windows 7)上看到该控件。

不幸的是,在设计时仍然看不到控件,但是我可以忍受!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 2021-12-29
    • 2012-12-07
    • 2021-01-06
    • 1970-01-01
    相关资源
    最近更新 更多