2009-11-17 73 views
0

我需要从旧版本的C++ Builder中编写的遗留Windows应用程序中打开html帮助文件。 HtmlHelp通过HtmlHelp.ocx加载,我通过LoadLibrary加载。OCX文件上的LoadLibrary在Windows 7中失败x64

这已经很好用了很多年,但它在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位的问题:我的应用程序是一个在C++ Builder 5中编译的32位可执行文件,所以如果我没有弄错它应该是一个32位的过程。或者我错了假设?

+0

GetLastError和FileMon会说什么? – 2009-11-17 16:50:13

+0

好点。见上面的第一个编辑。 – 2009-11-18 09:25:41

回答

1

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

1

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

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


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位进程将获得的视图。

+0

我的应用程序是一个在C++ Builder 5中编译的32位可执行文件,所以如果我没有弄错它应该是一个32位的过程。或者我错了假设? – 2009-11-17 12:52:44

+0

我必须承认,C++ Builder 5将会制作一个32位程序似乎非常引人注目。你通常必须努力创建和构建64位配置。 在这种情况下,ive在64位操作系统上添加了一些与诊断32位应用程序问题相关的信息。 – 2009-11-17 15:31:54

1

我有完全相同的问题,现在运行W7(x64)。

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

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