Question

Une application sur laquelle j'ai récemment commencé à travailler doit enregistrer deux dll, "à cause d'ActiveX".

Cela rend difficile la présence de plusieurs versions de l’application sur votre ordinateur, par exemple la version du produit installée et les versions Debug et Release des dernières sources de développement.

Quelles sont les alternatives à l'enregistrement pour ActiveX?

Était-ce utile?

La solution

Si votre application charge les objets ActiveX, vous avez le choix entre plusieurs options. Si vous utilisez XP ou une version plus récente, la première option consiste à utiliser une COM sans inscription avec un fichier manifeste comme expliqué à la section MSDN . L'idée est de déclarer vos composants COM (ActiveX) dans un fichier manifeste au lieu du registre. Donc, pour MyApp.exe, créez MyApp.exe.manifest avec les éléments suivants (en utilisant votre nom de fichier DLL et votre CLSID):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp_ActiveX" version="1.0.0.1" 
        processorArchitecture="x86" publicKeyToken="0000000000000000" />

  <file name="MyActiveX.dll">
    <comClass clsid="{0000000-0000-0000-0000-000000000000}" threadingModel="Both" />
  </file>
</assembly>

L’autre option mentionnée par DougN est de lancer votre propre CoCreateInstance () pour créer l’objet. Le code C ++ suivant (plus ATL) devrait le faire (en partant de la mémoire, vérifiez bien le code):

typedef int (__stdcall *LPDLLGETCLASSOBJECT)(REFCLSID, REFIID, void**);

// LoadInterface() - Load COM Interface from DLL without using registry.
//
// USAGE:   
//   HMODULE hModule = 0;
//   CComPtr<IMyActiveX> pActiveX;
//   if(SUCCEEDED(LoadInterface("C:\\Debug\\MyActiveX.dll", CLSID_MyActiveX, IID_IMyActiveX, (void**)&pActiveX, &hModule)))
//   {
//      // TODO: use pActiveX
// 
//      // caller must call FreeLibrary(hModule) when done
//      pActiveX = 0;
//      FreeLibrary(hModule); 
//   }
//
HRESULT LoadInterface(LPCTSTR pDllPath, REFCLSID rClsid, REFIID riid, LPVOID* ppv, HMODULE *pModule)
{
    if(pModule == 0 || ppv == 0) return E_POINTER;
    HMODULE hModule = LoadLibrary(pDllPath);
    if(hModule == 0) return E_FAIL;

    HREUSLT hr = E_POINTER;
    CComPtr<IClassFactory> classFactory;
    LPDLLGETCLASSOBJECT pGetClassObject = (LPDLLGETCLASSOBJECT)GetProcAddress(hModule, "DllGetClassObject");
    if(pGetClassObject)
    {
        hr = pGetClassObject(rClsid, IID_IClassFactory, (void**)&classFactory);
        if(SUCCEEDED(hr))
        {
            hr = classFactory->CreateInstance(0, riid, (void**)ppv);
            if(SUCCEEDED(hr))
            {
                *pModule = hModule;
                return S_OK;
            }
        }
    }

    // unload library on error
    if(hModule)  
    {
        FreeLibrary(hModule);
    }
    return hr;
 }

Autres conseils

Aucune que je puisse penser. C’est la raison d’être de COM (donc d’ActiveX).

Si vous contrôlez le code qui charge le contrôle ActiveX et que personne d'autre ne doit le charger, vous pouvez ignorer l'enregistrement et gérer manuellement vos propres appels CreateInstance: LoadLibrary, obtenir un pointeur sur l'objet Factory et créer directement des instances.

Cela sur un projet il y a environ 10 ans et cela a très bien fonctionné.

Cependant, si vous ne pouvez pas le faire (peut-être que vous ne maîtrisez pas le code appelant CreateInstance), créez simplement deux fichiers de commandes et placez-les sur votre bureau: un pour enregistrer Debug et un pour enregistrer les DLL de version. . Il est assez facile de changer d’aller-retour.

Vous pouvez créer une version des contrôles ActiveX à l'aide du ProgID .

Je ne pense pas que la solution .bat soit nécessairement horrible. La plupart des contrôles ActiveX simples s'auto-enregistrent / se désinscrivent. Mais cela vous limite toujours à exécuter une version de débogage ou une version finale à la fois, pas les deux simultanément.

C’est un gros problème (c’est l’essence de "DLL Hell"), qui explique en grande partie la popularité de .NET et de Java.

Je pense que .NET tire parti du partage côte à côte, une fonctionnalité introduite avec Windows 2000 et Windows 98 SE. Je ne pense pas que vous ayez besoin de .NET pour l'utiliser (vous n'avez pas dit que vous utilisiez COM Interop).

Un article assez long sur MSDN est disponible à l'adresse http://msdn.microsoft. .com / fr-us / library / ms811700.aspx , "Implémentation du partage de composants côte à côte dans les applications" qui suggère de créer un fichier .local. Je ne comprends pas très bien comment cela fonctionne, mais je pense que c'est la bonne approche.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top