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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top