Quali sono le alternative alla registrazione dll per ActiveX
-
03-07-2019 - |
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.
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.