Domanda

Un'applicazione su cui ho recentemente iniziato a lavorare deve registrare due DLL, "a causa di ActiveX".

Ciò rende difficile la presenza di più versioni dell'applicazione sul tuo computer, ad esempio la versione del prodotto installata e le versioni Debug e Release delle ultime fonti di sviluppo.

Quali sono le alternative alla registrazione per ActiveX.

È stato utile?

Soluzione

Se l'applicazione carica gli oggetti ActiveX, ci sono un paio di opzioni. La prima opzione se si utilizza XP o più recente, per utilizzare una COM senza registrazione con un file manifest come spiegato in MSDN . L'idea è di dichiarare i componenti COM (ActiveX) in un file manifest anziché nel registro. Quindi per MyApp.exe, crea MyApp.exe.manifest con il seguente (usando il nome del tuo file DLL e 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'altra opzione, come menzionato DougN, è quella di creare il proprio CoCreateInstance () per creare l'oggetto. Il seguente codice C ++ (più ATL) dovrebbe farlo (andando dalla memoria, quindi ricontrolla il codice):

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

Altri suggerimenti

Nessuno a cui riesco a pensare. Questa è l'intera logica alla base di COM (quindi ActiveX).

Se controlli il codice che carica il controllo ActiveX e nessun altro deve caricarlo, potresti saltare la registrazione e gestire manualmente le tue chiamate CreateInstance: LoadLibrary, ottenere un puntatore all'oggetto Factory e creare istanze direttamente.

L'ho fatto su un progetto circa 10 anni fa e ha funzionato alla grande.

Tuttavia, se non riesci a farlo (forse non controlli il codice che chiama CreateInstance), crea semplicemente due file batch e inseriscili sul desktop: uno per registrare il debug e uno per registrare le DLL di rilascio . Passare avanti e indietro diventa piuttosto semplice.

Puoi controllare i controlli ActiveX utilizzando ProgID .

Non credo che la soluzione .bat sia necessariamente orribile. I controlli ActiveX più semplici sono autoregistranti / non registrati. Ma ti limita comunque a eseguire una versione di debug o una versione di rilascio alla volta, non entrambe contemporaneamente.

È un grosso problema (è l'essenza di " DLL Hell ") e una grande parte del motivo della popolarità di .NET e Java.

Credo che .NET sfrutti la condivisione side-by-side, una funzionalità introdotta con Windows 2000 e Windows 98 SE. Non penso che tu abbia bisogno di .NET per usarlo (non hai detto che stavi facendo l'interoperabilità COM).

C'è un articolo piuttosto lungo su MSDN all'indirizzo http://msdn.microsoft .com / it-it / library / ms811700.aspx , " Implementazione della condivisione dei componenti side-by-side in Applicazioni " che suggerisce la creazione di un file .local. Non sono del tutto chiaro su come funzioni, ma penso che sia l'approccio giusto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top