Работа с незарегистрированными интерфейсами
От: Raul  
Дата: 06.08.02 17:41
Оценка:
Можно ли каким-нибудь образом получить незарегистрированный с системном реестре объект и соответсnвенно его дисп-интерфейсы? Аналогия — получение незарегистрированного ITypeLib. Т.е. есть ДЛЛ с прикомпонованной библиотекой типа и кучей объектов и интерфейсов, и есть желание работаь с ней не без регистрации (regsvr32.exe). Поможите, люди добрые, а то ведь могу и сам разобраться.
Re: DllGetClassObject
От: Vi2 Удмуртия http://www.adem.ru
Дата: 07.08.02 02:59
Оценка:
Здравствуйте Raul, Вы писали:

R>Можно ли каким-нибудь образом получить незарегистрированный с системном реестре объект и соответсnвенно его дисп-интерфейсы? Аналогия — получение незарегистрированного ITypeLib. Т.е. есть ДЛЛ с прикомпонованной библиотекой типа и кучей объектов и интерфейсов, и есть желание работаь с ней не без регистрации (regsvr32.exe). Поможите, люди добрые, а то ведь могу и сам разобраться.


А в чём проблема?

В каждой DLL есть 4 дополнительных, связанных с СОМ входа. Один из них — DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv). Передаёшь туда CLSID кокласса и IID_IClassFactory, получаешь класс-фактори, у неё просишь CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj) с IID_IDispatch. Маршаллинга тебе не треба, раз DLL. Что ещё нужно, чтобы "встретить достойную старость"?
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: DllGetClassObject
От: Аноним  
Дата: 07.08.02 15:51
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>А в чём проблема?

Vi2>В каждой DLL есть 4 дополнительных, связанных с СОМ входа. Один из них — DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv). Передаёшь туда CLSID кокласса и IID_IClassFactory, получаешь класс-фактори, у неё просишь CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj) с IID_IDispatch. Маршаллинга тебе не треба, раз DLL. Что ещё нужно, чтобы "встретить достойную старость"?

Возможно,я не совсем корректно описал заморочку.
А проблема вот в чем. Метод с DllGetClassObject работает, если сия библиотека уже зарегистрирована. А иначе — следующий кусок кода

    HRESULT hr;
    HINSTANCE hDll=::LoadLibrary("ordam20.dll");
    DWORD dw=GetLastError();
    HRESULT (STDAPICALLTYPE *pfnGetCo)(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
    (FARPROC&) pfnGetCo=::GetProcAddress(hDll,"DllGetClassObject");
    IClassFactory *piCf=NULL;
    hr=pfnGetCo(CLSID_ORAsyncConnection,IID_IClassFactory,(void**)&piCf);
    LPDISPATCH lpDisp=NULL;
    hr=piCf->CreateInstance(NULL,IID_IORAsyncConnection,(void**)&lpDisp);
/*    class Client_IORAsyncConnection : public COleDispatchDriver
    {
    ...
        long GetTimeout();
    ...
    };*/
    Client_IORAsyncConnection iAConn(lpDisp);
    long l=iAConn.GetTimeout(); //  throw COleException {m_sc=0x8002801D(библиотека не зарегистрирована)}


сваливается в COleException с SCODE 0x8002801D(библиотека не зарегистрирована). Возможно, это связано с реализацией собственно сервера — он регистрирует, помимо компонента с CLSID_ORAsyncConnection, еще пару СО и библиотеку типов; хотя я не уверен в том, что он использует эти объекты СОМ. К сожалению, реализация сервера не доступна, также, как и его разработчики. Вопрос — Есть ли еще какие-либо методы работы с незарегистрированными объектами СОМ.
Re[3]: DllGetClassObject
От: Vi2 Удмуртия http://www.adem.ru
Дата: 07.08.02 16:33
Оценка:
Здравствуйте Аноним, Вы писали:

А>сваливается в COleException с SCODE 0x8002801D(библиотека не зарегистрирована). Возможно, это связано с реализацией собственно сервера — он регистрирует, помимо компонента с CLSID_ORAsyncConnection, еще пару СО и библиотеку типов; хотя я не уверен в том, что он использует эти объекты СОМ. К сожалению, реализация сервера не доступна, также, как и его разработчики. Вопрос — Есть ли еще какие-либо методы работы с незарегистрированными объектами СОМ.


Скорее всего это связано с работой Invoke в объекте — он работает через ITypeInfo. Чтобы убедиться в этом, убери регистрацию этой DLL и сделай простую регистрацию TLB из DLL через REGTLIB.exe в ком.строке или RegisterTypeLib() в программе. Она зарегистрирует только TLB без коклассов. Если это не поможет, значит, она внутри создаёт коклассы. Тогда — увы — ничего сделать нельзя.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: DllGetClassObject
От: Vi2 Удмуртия http://www.adem.ru
Дата: 07.08.02 16:35
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Скорее всего это связано с работой Invoke в объекте — он работает через ITypeInfo. Чтобы убедиться в этом, убери регистрацию этой DLL и сделай простую регистрацию TLB из DLL через REGTLIB.exe в ком.строке или RegisterTypeLib() в программе. Она зарегистрирует только TLB без коклассов. Если это не поможет, значит, она внутри создаёт коклассы. Тогда — увы — ничего сделать нельзя.


Хотя, ты же сам можешь вызвать в начале DllRegisterServer и в конце DllUnregisterServer, оставляя Реестре нетронутым.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[5]: DllGetClassObject
От: Raul  
Дата: 07.08.02 17:28
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>>Скорее всего это связано с работой Invoke в объекте — он работает через ITypeInfo. Чтобы убедиться в этом, убери регистрацию этой DLL и сделай простую регистрацию TLB из DLL через REGTLIB.exe в ком.строке или RegisterTypeLib() в программе. Она зарегистрирует только TLB без коклассов. Если это не поможет, значит, она внутри создаёт коклассы. Тогда — увы — ничего сделать нельзя.


Vi2>Хотя, ты же сам можешь вызвать в начале DllRegisterServer и в конце DllUnregisterServer, оставляя Реестре нетронутым.


Действительно, методом научного тыка установлено, что упомянутый код работает, если в реестре есть ветка с описанием typelib данного сервака, все остальное можно удалить. Ну а в общем-то, я уже допер, как все это можно сделать в моем случае. Так что — всем спасибо (особенно Vi2), все свободны.
Re[6]: DllGetClassObject
От: Vi2 Удмуртия http://www.adem.ru
Дата: 08.08.02 02:54
Оценка:
Здравствуйте Raul, Вы писали:

R>Так что — всем спасибо (особенно Vi2), все свободны.


А мы и так свободны. Но, спасибо, что напомнили.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.