Pregunta

Una aplicación en la que comencé a trabajar recientemente tiene que registrar dos archivos DLL, " debido a ActiveX " ;.

Esto dificulta la presencia de varias versiones de la aplicación en su máquina; por ejemplo, la versión del producto instalado y las versiones de depuración y lanzamiento de las últimas fuentes de desarrollo.

¿Cuáles son las alternativas al registro para ActiveX?

¿Fue útil?

Solución

Si su aplicación carga los objetos ActiveX, hay un par de opciones. La primera opción si está utilizando XP o más reciente, usar un COM sin registro con un archivo de manifiesto como se explica en MSDN . La idea es declarar sus componentes COM (ActiveX) en un archivo de manifiesto en lugar del registro. Entonces, para MyApp.exe, cree MyApp.exe.manifest con lo siguiente (usando su nombre de archivo DLL y 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>

La otra opción como mencionó DougN es rodar su propia CoCreateInstance () para crear el objeto. El siguiente código C ++ (más ATL) debería hacerlo (yendo desde la memoria, así que verifique el código):

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

Otros consejos

Ninguno que se me ocurra. Esa es toda la razón detrás de COM (por lo tanto, ActiveX).

Si controla el código que carga el control ActiveX, y nadie más necesita cargarlo, puede omitir el registro y manejar manualmente sus propias llamadas CreateInstance: LoadLibrary, obtener un puntero al objeto Factory y crear instancias directamente.

Hizo eso en un proyecto hace unos 10 años y funcionó muy bien.

Sin embargo, si no puede hacerlo (tal vez no controle el código que llama a CreateInstance), simplemente cree dos archivos por lotes y colóquelos en su escritorio: uno para registrar la depuración y otro para registrar las DLL de lanzamiento. . Cambiar de un lado a otro se vuelve bastante fácil.

Puede versionar controles ActiveX utilizando el ProgID .

No creo que la solución .bat sea necesariamente horrible. La mayoría de los controles ActiveX simples son auto-registro / desregistro. Pero todavía lo limita a ejecutar una versión de depuración o una versión de lanzamiento a la vez, no ambas simultáneamente.

Es un gran problema (es la esencia de "DLL Hell"), y una gran parte de la razón de la popularidad de .NET y Java.

Creo que .NET aprovecha el uso compartido en paralelo, una característica introducida con Windows 2000 y Windows 98 SE. No creo que necesite .NET para usarlo (no dijo que estaba haciendo COM Interop).

Hay un artículo algo extenso sobre MSDN en http://msdn.microsoft .com / es-us / library / ms811700.aspx , " Implementando el uso compartido de componentes lado a lado en aplicaciones " lo que sugiere crear un archivo .local. No estoy completamente claro cómo funciona eso, pero creo que ese es el enfoque correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top