Quais são as alternativas para DLL de registro para ActiveX
-
03-07-2019 - |
Pergunta
Uma aplicação que recentemente começou a trabalhar no tem que registrar dois de dll, "por causa de ActiveX".
Isto torna difícil ter múltiplas versões do aplicativo presente na sua máquina - dizer a versão do produto instalada, e versões de depuração e lançamento da mais recente fontes de desenvolvimento.
Quais são as alternativas para o registro de ActiveX.
Solução
Se seu aplicativo carrega objetos do ActiveX, há um par de opções. A primeira opção se você estiver usando XP ou mais recente, o uso de um registro-Free COM com um arquivo de manifesto como explicado na MSDN . A ideia é declarar seus componentes COM (ActiveX) em um arquivo de manifesto em vez do Registro. Assim, para MyApp.exe, crie MyApp.exe.manifest com o seguinte (usando o nome do arquivo 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>
A outra opção como DougN mencionado é rolar o seu próprio CoCreateInstance () para criar o objeto. O seguinte código C ++ (mais ATL) deve fazê-lo (indo de memória para que verifique o 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;
}
Outras dicas
Não que eu possa pensar. Essa é a lógica por trás COM (assim ActiveX).
Se você controlar o código que carrega o controle ActiveX, e ninguém precisa outra pessoa para carregá-lo, você pode pular o registro e lidar manualmente as suas próprias chamadas CreateInstance: LoadLibrary, obter um ponteiro para o objeto de fábrica, e criar instâncias diretamente.
Será que isso em um projeto de cerca de 10 anos atrás e funcionou muito bem.
No entanto, se você não pode fazer isso (talvez você não controlar o código de chamada CreateInstance), então basta criar dois arquivos em lote e colocá-los no ambiente de trabalho: um para registar Debug, e um para registrar o DLLs lançamento . volta comutação e para trás, em seguida, torna-se muito fácil.
Você pode controles ActiveX versão usando o ProgID .
Eu não acho que a solução .bat é necessariamente horrível. A maioria dos controles ActiveX simples são auto-registrar / cancelar o registro. Mas ainda limita a executando uma versão de depuração ou de uma versão de cada vez, não ambos ao mesmo tempo.
É um grande problema (que é a essência de "DLL Hell"), e uma grande parte da razão para a popularidade do .NET e Java.
Eu acredito .NET leva vantagem de partilha side-by-side, um recurso introduzido com o Windows 2000 e Windows 98 SE. Eu não acho que você precisa .NET para usá-lo (você não disse que você estava fazendo COM Interop).
Há um pouco longo artigo no MSDN em http://msdn.microsoft .com / en-us / library / ms811700.aspx , "Implementando Side-by-Side Compartilhamento componente em aplicações", que sugere a criação de um arquivo .local. Eu não estou completamente clara sobre como isso funciona, mas eu acho que é a abordagem correta.