2009-11-17 13 views
0

Je dois ouvrir un fichier d'aide html à partir d'une ancienne application Windows écrite dans l'ancienne version de C++ Builder. HtmlHelp est chargé via HtmlHelp.ocx, que je charge via LoadLibrary.La bibliothèque LoadLibrary sur le fichier OCX échoue sous Windows 7 x64

Cela a fonctionné correctement pendant des années, mais cela ne fonctionne plus sous Windows 7 x64. Il peut également échouer sous Windows7 x86, mais je n'ai pas d'ordinateur avec ce système d'exploitation, donc je ne peux pas l'essayer pour le moment.

Je chargeais hhctrl.ocx dynamiquement comme suit:

#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; 
} 

j'ai vérifié si% SystemRoot% \ System32 \ hhctrl.ocx existe sur le système Windows 7 et il le fait.

Pourquoi le chargement via LoadLibrary échoue-t-il? Comment puis-je contourner ce problème?

EDIT: GetLastError dit (en allemand, donc je ne fais que traduire): "Impossible de trouver le fichier." Mais j'ai débogué la fonction et le chemin est "% SystemRoot% \ System32 \ hhctrl.ocx" et le fichier existe. En outre, étant donné que deux réponses pointent vers des problèmes 64 bits vs 32 bits: Mon application est un exécutable 32 bits compilé dans C++ Builder 5, il devrait donc s'agir d'un processus 32 bits si je ne me trompe pas . Ou ai-je tort de supposer cela?

+0

Que disent GetLastError et FileMon? –

+0

Bon point. Voir première modification ci-dessus. –

Répondre

1

Utilisez la fonction ExpandEnvironmentStrings pour développer% SystemRoot% \ System32 \ hhctrl.ocx en chemin réel sur l'installation de l'utilisateur. Le système d'exploitation 64bit redirigera correctement le chemin étendu vers la DLL 32 bits.

1

Vous ne pouvez pas charger des DLL 32 bits dans un processus 64 bits, et vice versa. Les contrôles ActiveX sont, bien sûr, des DLL.

Vous pouvez parfois contourner ce problème en demandant à l'ActiveX 32 bits de se charger en tant que serveur hors processus - il est ensuite hébergé dans un processus séparé de 32 bits (ou 64 bits), selon le cas. Cela nécessite que les interfaces ActiveX n'utilisent que des interfaces que le système sait déjà comment faire marcher, et/ou que le projet ait construit des versions 64 bits ET 32 bits du fichier stub dll proxy.


Depends est un outil qui est très utile lorsque vous avez besoin de comprendre pourquoi Dlls wont charge. Bien sûr, en tant qu'application 32 bits sur un système d'exploitation 64 bits, vous devez savoir que les applications 32 bits n'accèdent pas à %SYSTEMROOT%\System32 et ne lisent pas et n'écrivent pas directement depuis HKCR. System32 contient en fait les binaires 64 bits du système d'exploitation et HKCR contient les entrées de registre pour les applications 64 bits. Un processus de noyau appelé 'réflexion' redirige complètement les applications 32bit de System32 vers %SYSTEMROOT%\SysWow64. De même, l'accès au registre à HKEY_CLASSES_ROOT est redirigé vers `HKEY_CLASSES_ROOT \ Wow6432Node '. Vous devez le savoir, car Explorer et regedit sont des processus en 64 bits et vous montreront volontiers le contenu 64 bits de System32 et HKCR. Vous devez naviguer explicitement vers les nœuds 32 bits pour vérifier l'affichage de votre processus 32 bits.

+0

Mon application est un exécutable 32 bits compilé dans C++ Builder 5, donc ce devrait être un processus de 32 bits si je ne me trompe pas. Ou ai-je tort de supposer cela? –

+0

Je dois admettre qu'il semble très convaincant que C++ Builder 5 va faire un processus 32 bits. Vous devez généralement essayer relativement dur de créer et de construire une configuration 64 bits. Dans ce cas, ive a ajouté quelques informations pertinentes pour diagnostiquer les problèmes avec les applications 32 bits sur les systèmes d'exploitation 64 bits à ma réponse. –

1

J'ai exactement le même problème en ce moment en cours d'exécution W7 (x64). Je l'ai eu pour fonctionner quand j'ai changé le "% SystemRoot% \ System32 \ hhctrl.ocx" en "c: \ windows \ System32 \ hhctrl.ocx", mais je suppose que je dois comprendre pourquoi% SystemRoot% résout faux. Btw: Je construis une application 32 bits sur BCB2007.