0

古いバージョンのC++Builderで記述されたレガシーWindowsアプリケーション内からhtmlヘルプファイルを開く必要があります。HtmlHelpは、LoadLibraryを介してロードしているHtmlHelp.ocxを介してロードされます。

これは何年も問題なく機能していましたが、Windows7x64では機能しなくなりました。Windows7 x86でも失敗する可能性がありますが、このOSを搭載したコンピューターがないため、現時点では試してみることができません。

次のように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がWindows7システムに存在するかどうかを確認しました。

LoadLibraryを介したロードが失敗するのはなぜですか?この問題を回避するにはどうすればよいですか?

編集: GetLastErrorは(ドイツ語で、私はただ翻訳しているだけです)と言います:「ファイルが見つかりませんでした。」しかし、関数をデバッグしたところ、パスは「%SystemRoot%\ System32 \ hhctrl.ocx」であり、ファイルは存在します。

また、2つの答えが64ビットと32ビットの問題の方向を示しているため、私のアプリケーションはC ++ Builder 5でコンパイルされた32ビットの実行可能ファイルであるため、間違えなければ32ビットのプロセスになるはずです。それとも私はそれを仮定するのは間違っていますか?

4

3 に答える 3

1

You can't load 32bit dlls in a 64bit process, and visa versa. ActiveX controls are, of course, Dlls.

You can sometimes work around this by getting the 32bit ActiveX to load as an out-of-process server - its then hosted in a seperate 32bit (or 64bit) process as appropriate. This requires that the ActiveX onlyuses interfaces the system already knows how to marshal, and/or the project built 64bit AND 32bit versions of the proxy stub dll.


Depends is a tool that is very useful when you need to figure out why Dlls wont load. Of course, as a 32 bit application on a 64bit OS you need to know that 32 bit applications do NOT get access to %SYSTEMROOT%\System32 and, also do NOT read and write from HKCR directly. System32 actually contains the 64bit OS binaries, and HKCR contains the registry entries for 64bit apps.

A kernel process called 'reflection' redirects 32bit apps completely transparently to from System32 to %SYSTEMROOT%\SysWow64. Likewise, registry access to HKEY_CLASSES_ROOT is redirected to `HKEY_CLASSES_ROOT\Wow6432Node'. You need to know this of course, because explorer and regedit are 64bit processes and will happily show you the 64bit contents of System32 and HKCR. You need to explicitly navigate to the 32bit nodes to double check the view your 32bit process is going to get.

于 2009-11-17T12:43:18.737 に答える
1

ExpandEnvironmentStrings関数を使用 して、%SystemRoot%\ System32\hhctrl.ocxをユーザーのインストールの実際のパスに展開します。64ビットOSは、拡張パスを32ビットdllに正しくリダイレ​​クトします。

于 2010-06-22T09:00:51.790 に答える
1

現在、W7(x64)を実行しているときにまったく同じ問題が発生します。

「%SystemRoot%\ System32 \ hhctrl.ocx」を「c:\ windows \ System32 \ hhctrl.ocx」に変更すると機能するようになりましたが、%SystemRoot%が間違って解決される理由を理解する必要があると思います。

ところで:私はBCB2007で32ビットアプリを構築しています。

于 2010-01-12T13:45:41.817 に答える