OCX文件上的LoadLibrary在Windows 7 x64中失败

时间:2009-11-17 12:37:16

标签: winapi windows-7 html-helper loadlibrary chm

我需要在用旧版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位进程。或者我认为错了?

3 个答案:

答案 0 :(得分:1)

你无法在64位进程中加载​​32位dll,反之亦然。 ActiveX控件当然是Dlls。

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


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

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

答案 1 :(得分:1)

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

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

btw:我正在BCB2007上构建一个32位应用程序。

答案 2 :(得分:1)

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