Сбой LoadLibrary на файл OCX в Windows 7 x64 - PullRequest
0 голосов
/ 17 ноября 2009

Мне нужно открыть HTML-файл справки из старого приложения Windows, написанного в старой версии C ++ Builder. 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;
}

Я проверил, существует ли% SystemRoot% \ System32 \ hhctrl.ocx в системе Windows 7, и он существует.

Почему при загрузке через LoadLibrary происходит сбой? Как я могу обойти эту проблему?

РЕДАКТИРОВАТЬ: GetLastError говорит (на немецком языке, поэтому я просто переводить): «Не удалось найти файл». Но я отладил функцию, и путь «% SystemRoot% \ System32 \ hhctrl.ocx», и файл существует.

Кроме того, поскольку два ответа указывают в направлении 64-битных и 32-битных проблем: мое приложение представляет собой 32-битный исполняемый файл, скомпилированный в C ++ Builder 5, поэтому это должен быть 32-битный процесс, если я не ошибаюсь. Или я ошибаюсь, предполагая это?

Ответы [ 3 ]

1 голос
/ 12 января 2010

У меня точно такая же проблема сейчас работает W7 (x64).

Я заставил его работать, когда я изменил "% SystemRoot% \ System32 \ hhctrl.ocx" на "c: \ windows \ System32 \ hhctrl.ocx", но я должен выяснить, почему разрешается% SystemRoot% неправильно.

Кстати: я создаю 32-битное приложение на BCB2007.

1 голос
/ 22 июня 2010

Используйте ExpandEnvironmentStrings , чтобы развернуть% SystemRoot% \ System32 \ hhctrl.ocx к реальному пути при инсталляции пользователя. 64-битная ОС будет перенаправлять расширенный путь к 32-битной DLL правильно.

1 голос
/ 17 ноября 2009

Вы не можете загрузить 32-битные библиотеки в 64-битном процессе, и наоборот. Элементы управления ActiveX, конечно же, Dlls.

Иногда можно обойти эту проблему, загрузив 32-битный ActiveX для загрузки в качестве сервера вне процесса - его затем размещают в отдельном 32-битном (или 64-битном) процессе в зависимости от ситуации. Для этого необходимо, чтобы ActiveX использовал только интерфейсы, которые система уже знает, как выполнить маршалинг, и / или проект создал 64-битные и 32-битные версии заглушки прокси-сервера dll.


Зависит - это инструмент, который очень полезен, когда вам нужно выяснить, почему Dlls не загружается. Конечно, как 32-битное приложение в 64-битной ОС, вы должны знать, что 32-битные приложения НЕ получают доступ к %SYSTEMROOT%\System32, а также НЕ читают и не пишут напрямую из HKCR. System32 фактически содержит двоичные файлы 64-битных ОС, а HKCR содержит записи реестра для 64-битных приложений.

Процесс ядра, называемый «отражением», полностью прозрачно перенаправляет 32-битные приложения с System32 на %SYSTEMROOT%\SysWow64. Аналогично, доступ к реестру к HKEY_CLASSES_ROOT перенаправляется на `HKEY_CLASSES_ROOT \ Wow6432Node '. Конечно, вы должны это знать, потому что explorer и regedit являются 64-битными процессами и с радостью покажут вам 64-битное содержимое System32 и HKCR. Вам необходимо явно перейти к 32-битным узлам, чтобы дважды проверить представление, которое получит ваш 32-битный процесс.

...