Какие есть альтернативы регистрации dll для ActiveX

Приложение, над которым я недавно начал работать, должно зарегистрировать две dll «из-за ActiveX».

Это затрудняет наличие нескольких версий приложения на вашем компьютере — скажем, установленную версию продукта, а также отладочные и выпускные версии последних исходных кодов разработки.

Какие есть альтернативы регистрации для ActiveX.


person mealnor    schedule 01.05.2009    source источник


Ответы (5)


Если ваше приложение загружает объекты ActiveX, есть несколько вариантов. Первый вариант, если вы используете XP или новее, это использовать COM без регистрации с файлом манифеста, как описано на MSDN. Идея состоит в том, чтобы объявить ваши компоненты COM (ActiveX) в файле манифеста, а не в реестре. Итак, для MyApp.exe создайте MyApp.exe.manifest со следующим (используя имя файла DLL и 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>

Другой вариант, как упомянул DougN, - это свернуть свой собственный CoCreateInstance() для создания объекта. Следующий код C++ (плюс ATL) должен сделать это (исходя из памяти, поэтому дважды проверьте код):

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;
 }
person Jeff Youel    schedule 02.05.2009

Нет, о чем я могу думать. В этом вся суть COM (таким образом, ActiveX).

person Otávio Décio    schedule 01.05.2009

Если вы управляете кодом, который загружает элемент управления ActiveX, и никому больше не нужно его загружать, вы можете пропустить регистрацию и вручную обработать свои собственные вызовы CreateInstance: LoadLibrary, получить указатель на объект Factory и создать экземпляры напрямую.

Сделал это в проекте около 10 лет назад, и это сработало отлично.

Однако, если вы не можете этого сделать (возможно, вы не контролируете код, вызывающий CreateInstance), просто создайте два пакетных файла и поместите их на рабочий стол: один для регистрации отладки и один для регистрации библиотек DLL выпуска. Затем переключаться туда и обратно становится довольно легко.

person DougN    schedule 01.05.2009
comment
трюк с .bat - ужасная идея - вы можете отменить регистрацию других версий приложений, установленных в этой системе. - person Francis; 01.05.2009

Вы можете управлять версиями элементов управления ActiveX, используя ProgID.

person i_am_jorf    schedule 01.05.2009

Я не думаю, что решение .bat обязательно ужасно. Большинство простых элементов управления ActiveX регистрируются/отменяются самостоятельно. Но это по-прежнему ограничивает вас запуском либо отладочной версии, либо версии выпуска за раз, а не одновременно.

Это большая проблема (в этом суть «DLL-ада») и большая часть причины популярности .NET и Java.

Я полагаю, что .NET использует преимущества параллельного совместного использования, функции, представленной в Windows 2000 и Windows 98 SE. Я не думаю, что вам нужен .NET для его использования (вы не сказали, что занимаетесь COM-взаимодействием).

В MSDN есть довольно длинная статья по адресу http://msdn.microsoft.com/en-us/library/ms811700.aspx, «Реализация параллельного совместного использования компонентов в приложениях», в котором предлагается создать файл .local. Я не совсем понимаю, как это работает, но я думаю, что это правильный подход.

person Alan McBee    schedule 06.05.2009