Каковы альтернативы регистрации DLL для ActiveX - PullRequest
2 голосов
/ 01 мая 2009

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

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

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

Ответы [ 5 ]

3 голосов
/ 02 мая 2009

Если ваше приложение загружает объекты 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>

Другой вариант, о котором упоминал Дугн, - это бросить свой собственный 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;
 }
0 голосов
/ 06 мая 2009

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

Это большая проблема (это сущность "DLL Hell") и большая часть причины популярности .NET и Java.

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

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

0 голосов
/ 01 мая 2009

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

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

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

0 голосов
/ 01 мая 2009

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

0 голосов
/ 01 мая 2009

Ни о чем я не могу думать. Вот и вся логика COM (то есть ActiveX).

...