0

我需要从用旧版 C++ Builder 编写的旧 Windows 应用程序中打开一个 html 帮助文件。HtmlHelp 是通过 HtmlHelp.ocx 加载的,我是通过 LoadLibrary 加载的。

这多年来一直运行良好,但在 Windows 7 x64 中不再适用。在 Windows7 x86 下它也可能会失败,但我没有任何具有此操作系统的计算机,因此我目前无法尝试。

我正在动态加载 hhctrl.ocx,如下所示:

#define HHPathRegKey "CLSID\\{adb880a6-d8ff-11cf-9377-00aa003b7a11}\\InprocServer32"

bool THTMLHelper::LoadHtmlHelp()
{
  HKEY HHKey;
  DWORD PathSize = 255;
  char Path[255];
  bool R = false;

  if (::RegOpenKeyExA(HKEY_CLASSES_ROOT, HHPathRegKey, 0, KEY_QUERY_VALUE, (void **)&HHKey) == ERROR_SUCCESS)
  {
    if (::RegQueryValueExA(HHKey, "", NULL, NULL, (LPBYTE)Path, &PathSize) == ERROR_SUCCESS)
    {
      //*****************************************
      //LOADING FAILS HERE
      //PATH IS %SystemRoot%\System32\hhctrl.ocx          
      //*****************************************
      HHLibrary = ::LoadLibrary(Path);
      if (HHLibrary != 0)
      {
        __HtmlHelp = (HTML_HELP_PROC) ::GetProcAddress(HHLibrary, "HtmlHelpA");
        R = (__HtmlHelp != NULL);
        if (!R)
        {
          ::FreeLibrary(HHLibrary);
          HHLibrary = 0;
        }
      }
    }
    ::RegCloseKey(HHKey);
  }
  return R;
}

我检查了 Windows 7 系统上是否存在 %SystemRoot%\System32\hhctrl.ocx 并且确实存在。

为什么通过 LoadLibrary 加载它会失败?我该如何解决这个问题?

编辑: GetLastError 说(用德语,所以我只是在翻译):“找不到文件。” 但我调试了函数,路径是“%SystemRoot%\System32\hhctrl.ocx”,文件确实存在。

此外,由于两个答案指向 64 位与 32 位问题的方向:我的应用程序是在 C++ Builder 5 中编译的 32 位可执行文件,因此如果我没记错的话,它应该是 32 位进程。还是我错误地假设?

4

3 回答 3

1

使用 ExpandEnvironmentStrings函数将 %SystemRoot%\System32\hhctrl.ocx 扩展为用户安装的真实路径。64 位操作系统将扩展路径正确重定向到 32 位 dll。

于 2010-06-22T09:00:51.790 回答
1

您不能在 64 位进程中加载​​ 32 位 dll,反之亦然。ActiveX 控件当然是 Dll。

有时您可以通过将 32 位 ActiveX 作为进程外服务器加载来解决此问题 - 然后将其托管在适当的单独的 32 位(或 64 位)进程中。这要求 ActiveX 只使用系统已经知道如何编组的接口,和/或项目构建了 64 位和 32 位版本的代理存根 dll。


Depends是一个非常有用的工具,当您需要找出 Dll 无法加载的原因时。当然,作为 64 位操作系统上的 32 位应用程序,您需要知道 32 位应用程序不能访问%SYSTEMROOT%\System32,也不能HKCR直接读取和写入。System32 实际上包含 64 位操作系统二进制文件,而 HKCR 包含 64 位应用程序的注册表项。

一个名为“反射”的内核进程将 32 位应用程序完全透明地从 System32 重定向到%SYSTEMROOT%\SysWow64. 同样,注册表访问HKEY_CLASSES_ROOT被重定向到“HKEY_CLASSES_ROOT\Wow6432Node”。你当然需要知道这一点,因为 explorer 和 regedit 是 64 位进程,会很高兴地向你展示 System32 和 HKCR 的 64 位内容。您需要明确导航到 32 位节点以仔细检查您的 32 位进程将获得的视图。

于 2009-11-17T12:43:18.737 回答
1

我现在运行 W7 (x64) 时遇到完全相同的问题。

当我将“%SystemRoot%\System32\hhctrl.ocx”更改为“c:\windows\System32\hhctrl.ocx”时,我让它工作了,但我想我需要弄清楚为什么 %SystemRoot% 解析错误。

顺便说一句:我正在 BCB2007 上构建一个 32 位应用程序。

于 2010-01-12T13:45:41.817 回答