WDMclient
Гость
|
|
« : 28-12-2009 03:53 » |
|
Есть сервер , обычный , например простейший ATL. Сервер локальный то бишь EXE. Проблема такая: клиентское приложение создает объект этого сервера, а потом выгружается , но надо что бы сервер продолжал висеть в памяти , и продолжал функционировать. Делаю AddRef , но зараза сервер потом автоматически вызывает Release ровно столько же раз сколько и AddRef.
Срабатывает только один способ резкое закрытие клиента - например вызывать TerminateProcess(GetCurrentProcess() , 0); или если клиент консольны то закрыть окно мышью , тогда сервер продолжает висеть.
В принципе такой метод ничем не вредит общей задаче , но может есть официальный способ? P.S. Уже два дня парюсь , все АПИ для блокировки COM перебрал %=/
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 28-12-2009 04:14 » |
|
Может стоит сделать приложение, задачей которого будет блокировка твоего COM в памяти?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zubr
Гость
|
|
« Ответ #2 : 28-12-2009 05:15 » |
|
1. Создаешь приложение, которое только умеет открывать и закрывать COM-сервер. 2. Приложение, которое работает с COM-сервером подключается к нему через GetActiveObject
|
|
|
Записан
|
|
|
|
WDMclient
Гость
|
|
« Ответ #3 : 31-12-2009 01:40 » |
|
Вроде по условию: одно приложение запускает сервер1 , сервер1 генерит уникальное имя, под которым приложение тоже регистрируется как сервер2. в общем сервер1 остается в памяти и если к нему подключается клиент , то передает имя сервера2. Клиент соеденяется с сервером2.
Вот ведь удивительно что грубое завершение TerminateProcess - никак не противоречит этой цели , сервер остается работать как положено. Видимо завязки где то в SCM менеджере , который весь этот блин-комный регулирует. в общем в чистой теории этого и не должно быть.
|
|
|
Записан
|
|
|
|
sss
Специалист
Offline
|
|
« Ответ #4 : 31-12-2009 02:23 » |
|
WDMclient, при чем здесь SCM менеджер ?
|
|
|
Записан
|
while (8==8)
|
|
|
WDMclient
Гость
|
|
« Ответ #5 : 31-12-2009 08:34 » |
|
Так ведь этот SCM управляет COMами А упомянул я его , так , к слову :=))
Тут у меня непонятки с функцией GetActiveObject , и клиент виснет по окончанию работы. Ведь для начала надо вроде бы зарегить серверный объект в таблице ROT
Тут у меня например (НЕ ATL) server.EXE
вот как он регится у меня.
DWORD regID = 0 , regActive = 0; IClassFactory* Share_Factory_Obj = new Share_ClassFactory ; //регистрирурую (где-то) фабрику CoRegisterClassObject( CLSID_ShareMem, (IClassFactory*)Share_Factory_Obj, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE,®ID);
//опять что ли регистрирую фабрику (в таблице ROT) RegisterActiveObject ( Share_Factory_Obj, CLSID_ShareMem, 0 , ®Active );
WHILE .......цикл сообщений
// Разрегистрация RevokeActiveObject(regActive , NULL); CoRevokeClassObject(regID);
============================================= Клиент делает тоже просто IStatus * shareMem=0 ;
CoCreateInstance(CLSID_CoShareMemory , NULL , CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , IID_IStatus, (void**)&shareMem );
IUnknown * punk; GetActiveObject(CLSID_CoShareMemory , NULL , & punk);
Может я неправильно регистрирую ?
|
|
|
Записан
|
|
|
|
WDMclient
Гость
|
|
« Ответ #6 : 31-12-2009 10:52 » |
|
Наверно несколько правильнее так для клиента. Тока что лежит в punk - неизвестно.(пока) hr=GetActiveObject(CLSID_CoShareMemory , NULL ,(IUnknown**) & punk); if(hr==S_OK) { punk->Release()l; } else { CoCreateInstance(CLSID_CoShareMemory , NULL , CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , IID_IStatus, (void**)&shareMem ); }
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #7 : 31-12-2009 19:58 » |
|
WDMclient, ... но надо что бы сервер продолжал висеть в памяти , и продолжал функционировать... а можно полюбопытствовать, зачем это надо?
|
|
|
Записан
|
С уважением Lapulya
|
|
|
WDMclient
Гость
|
|
« Ответ #8 : 31-12-2009 20:02 » |
|
в общем сработало , после 3х стопарей водки , вроде регистрировать объект сервера надо в процессе самого сервера. грубо это выглядит так в фабричной CreateInstance где он создается. И в принципе не надо уже ничего делать , в клиенте даже не надо вызывать GetActiveObject. Сервер исправно висит в памяти. HRESULT _stdcall Share_ClassFactory::CreateInstance (LPUNKNOWN pUnk, REFIID riid, void** ppv) {
if(pUnk != NULL)
{ return CLASS_E_NOAGGREGATION; }
CoShareMemory * pMem_Object = new CoShareMemory();
HRESULT hr = pMem_Object->QueryInterface(riid, ppv);
if(FAILED(hr)) delete pMem_Object;
DWORD regActive = 0 ; hr = RegisterActiveObject ( pMem_Object, CLSID_ShareMem, 0 , ®Active );
return hr; }
|
|
|
Записан
|
|
|
|
WDMclient
Гость
|
|
« Ответ #9 : 31-12-2009 20:09 » |
|
WDMclient, ... но надо что бы сервер продолжал висеть в памяти , и продолжал функционировать... а можно полюбопытствовать, зачем это надо? Да так я тестовое приложение делаю , правда не особо спешу , работодатель типа проверяет мою квалификацию(мать его с новым годом)
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #10 : 01-01-2010 10:45 » |
|
WDMclient, а не боишься, что работодатель может прочитать твои сообщения на форуме? З.Ы. Работодатель и тестовое задание мне известны.
|
|
|
Записан
|
|
|
|
WDMclient
Гость
|
|
« Ответ #11 : 01-01-2010 18:34 » |
|
Работадатели форумы не читают :=)) WDMclient, а не боишься, что работодатель может прочитать твои сообщения на форуме? З.Ы. Работодатель и тестовое задание мне известны.
Можешь что нить конкрентное сказать об нем?
|
|
« Последнее редактирование: 02-01-2010 07:23 от WDMclient »
|
Записан
|
|
|
|
|