Можно ли как-то получить COM-объект, который находится в рамках приложения, запущенного как сервис? Почему-то CreateInstance() пытается создать еще один экземпляр приложения.
Здравствуйте, Аноним, Вы писали:
А>Привет.
А>Можно ли как-то получить COM-объект, который находится в рамках приложения, запущенного как сервис? Почему-то CreateInstance() пытается создать еще один экземпляр приложения.
А>Заранее спасибо.
Зарегистрировать его в ROT через IRunningObjectTable.Register с флагом ROTFLAGS_ALLOWANYCLIENT. Получать можно как через этот интерфейс, так и хелпером GetActiveObject.
"Нормальные герои всегда идут в обход!"
Re[2]: Доступ к COM-объекту, который в виде сервиса
Да, действительно, помогло зарегистрировать объект в ROT. Получаю в другом модуле его из того же самого IRegisterObjectTable. С помощью GetObject(), задав IMoniker правильный.
Однако возникла следующая проблема: сам мой объект внутри себя тоже содержит COM-объекты (вектор). Раньше, получив основной, можно было вызывать его метод Get() и получать "внутренности". (Без абстракций: основной класс — IDataServer, внутренности — IDSTable (их несколько)). Сейчас же, если так делать, указатель на IDSTable инициализируется, но при любом обращении к нему вылезает COM Exception 800706F4. Что делать в такой ситуации? Тоже каждый IDSTable регистрировать в ROT?
Re[4]: Доступ к COM-объекту, который в виде сервиса
Здравствуйте, spy__, Вы писали:
__> Тоже каждый IDSTable регистрировать в ROT?
Да нет, и так должно работать. Вообще регистрировать в ROT рутовый объект — самый простой путь, однако можно обойтись и без такой регистрации, просто это расписывать несколько дольше. Вообще-то я думал, что по приведённой ссылке рассмотрены оба варианта, нет? Значит, я просто забыл. Но где-то там рядом должен быть и пример работы с сервисом без ROT, если конечно память мне опять не изменяет
COM Exception 800706F4 — это RPC_X_NULL_REF_POINTER, и насколько мне известно, генерится оно заглушкой, когда Вы передаёте каким-то параметром NULL, а заглушка ожидает в нём валидный указатель. В эту сторону надо копать.
__>Раньше, получив основной, можно было вызывать его метод
А это "раньше" он у Вас не инпроцессным сервером, часом, был?
Здравствуйте, Аноним, Вы писали:
А>Привет.
А>Можно ли как-то получить COM-объект, который находится в рамках приложения, запущенного как сервис? Почему-то CreateInstance() пытается создать еще один экземпляр приложения.
А>Заранее спасибо.
Привет,
как уже писали можно использовать ROT, можно прописать макрос DECLARE_CLASSFACTORY_SINGLETON в классе com-объекта и использовать обычный CoCreateInstance. В случае если ты создаешь com-объект в сервисе необходимо предварительно сделать вызов ф-ции CoInitializeSecurity, чтобы разрешить доступ к объекту.
Re[5]: Доступ к COM-объекту, который в виде сервиса
С регистрацией в ROT я разобрался. Единственный момент, который не работает (и в данный момент очень важен) — это проблема с Win 2003 Server. Ошибка 0x80004015. В интернетах пишут про CoInitializeSecurity(), но я пока не нашел объяснения доступным языком. Пробовал вызывать функцию из моего сервиса:
Здравствуйте, spy__, Вы писали:
__>С регистрацией в ROT я разобрался. Единственный момент, который не работает (и в данный момент очень важен) — это проблема с Win 2003 Server. Ошибка 0x80004015. В интернетах пишут про CoInitializeSecurity(), но я пока не нашел объяснения доступным языком. Пробовал вызывать функцию из моего сервиса:
__>
Здравствуйте, michae1, Вы писали:
M>Здравствуйте, spy__, Вы писали:
__>>С регистрацией в ROT я разобрался. Единственный момент, который не работает (и в данный момент очень важен) — это проблема с Win 2003 Server. Ошибка 0x80004015. В интернетах пишут про CoInitializeSecurity(), но я пока не нашел объяснения доступным языком. Пробовал вызывать функцию из моего сервиса:
__>>
__>>Резльтат S_OK, но регистрация все равно не проходит. Что я делаю не так?
__>>Заранее спасибо.
M>Возможно поможет это: здесь, M>обсуждалось здесь
Само приложение у меня (которое объект содержит регистрируемый в ROT) работает не как сервис. Его запускает другое, которое является сервисом. То есть мое висит в процессах, но в сервисах его нет.
Re[8]: Доступ к COM-объекту, который в виде сервиса
skip
__>Само приложение у меня (которое объект содержит регистрируемый в ROT) работает не как сервис. Его запускает другое, которое является сервисом. То есть мое висит в процессах, но в сервисах его нет.
Это не важно, если сервис у тебя запущен под Local Service, то процесс который будет порожден тоже будет под этим аккаунтом. Если не ошибаюсь при работе с ROT учитывается не только IL, но и аккаунт под которым объект был добавлен.
Попробуй забить на ROT и работать через CreateInstance и макрос DECLARE_CLASSFACTORY_SINGLETON (если архитектура позволят) так как я описал ниже. У меня под 7 такая схема успешно работает.
P.S. Если не поможет, напиши больше информации об архитектуре приложения: что, откуда и зачем вызывается? а то трудно понять в чем беда
Re[6]: Доступ к COM-объекту, который в виде сервиса
Здравствуйте, spy__, Вы писали:
__>С регистрацией в ROT я разобрался.
А что было-то?
__>Единственный момент, который не работает (и в данный момент очень важен) — это проблема с Win 2003 Server. Ошибка 0x80004015.
CoInitializeSecurity Вам не поможет, она не влияет на RunAs, а именно её Вам надо настроить, плюс раздать права на работу с сервером нужным пользователям. Но в такой конфигурации, как Вы описали
Само приложение у меня (которое объект содержит регистрируемый в ROT) работает не как сервис. Его запускает другое, которое является сервисом.
даже затрудняюсь сказать, как настраивать По идее, нужно указать в RunAs пользователя, под которым будет работать Ваше приложение. Но в Вашем случае это LocalSystem, а его можно указать только для COM-серверов в виде сервиса. Вам обязательно работать под LocalSystem? Может подойдёт специально созданный пользователь, пол него и настроить защиту сервера? Правда, возни и в этом случае будет прилично, если не подходит запуск службы под ним-же — придётся программно давать ему доступ к станции и десктопу службы, да и другие грабли возможны.
"Нормальные герои всегда идут в обход!"
Re[7]: Доступ к COM-объекту, который в виде сервиса
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, spy__, Вы писали:
__>>С регистрацией в ROT я разобрался.
JR>А что было-то?
__>>Единственный момент, который не работает (и в данный момент очень важен) — это проблема с Win 2003 Server. Ошибка 0x80004015.
JR>CoInitializeSecurity Вам не поможет, она не влияет на RunAs, а именно её Вам надо настроить, плюс раздать права на работу с сервером нужным пользователям. Но в такой конфигурации, как Вы описали
JR>
JR>Само приложение у меня (которое объект содержит регистрируемый в ROT) работает не как сервис. Его запускает другое, которое является сервисом.
JR> даже затрудняюсь сказать, как настраивать По идее, нужно указать в RunAs пользователя, под которым будет работать Ваше приложение. Но в Вашем случае это LocalSystem, а его можно указать только для COM-серверов в виде сервиса. Вам обязательно работать под LocalSystem? Может подойдёт специально созданный пользователь, пол него и настроить защиту сервера? Правда, возни и в этом случае будет прилично, если не подходит запуск службы под ним-же — придётся программно давать ему доступ к станции и десктопу службы, да и другие грабли возможны.
Я пока раскопал, что сервисы запускаются в 0 сессии. Соответственно, мой сервис все стартует также в 0 сессии. Но задача еще в том, чтобы можно было обращаться к объекту из других сессий. На Windows Vista у меня нет проблем с подменой Session ID процессу: все гладко и ровно, стартуются все процессы там где надо. На 2003 винде в процессах показывается мой, и даже сессия у него отображена та, которую я настраиваю, но остальное ничего не работает. Он как будто suspend. Короче, лажа какая-то с этой виндой. Ничерта там не работает.
Re[8]: Доступ к COM-объекту, который в виде сервиса
Разница между Vista и предыдущими версиями по части сессий в том, что на Vista нулевая сессия выделена исключительно под сервисы, а ранее она-же была и первой интерактивной. Но сессия — это только верхний, так сказать, уровень. Кроме них есть ещё Window stations, которые отдельно для интерактивного юзера, отдельно для служб, причём для служб их стандартно обычно несколько. Плюс ещё один "водораздел" системы безопасности — связанные со станциями desktops, к которым подключаются потоки. И эти десктопы влияют на, например, пхождение сообщений окнам. Ваши проблемы кроются, видимо, где-то в этих областях, но "ничего не работает" — это слишком расплывчато, да и "удалённая отладка" через форум вряд-ли будет эффективна. Стоит попытаться зацепиться за какую-то конкретную проблему и размотать до конца. Удачи
Здравствуйте, Аноним, Вы писали:
А>Привет. А>Можно ли как-то получить COM-объект, который находится в рамках приложения, запущенного как сервис? Почему-то CreateInstance() пытается создать еще один экземпляр приложения. А>Заранее спасибо.
Возможно я не правильно понял...
CoRegisterClassObject(...,...,...,REGCLS_MULTIPLEUSE,...)
Тогда DCOM буде вынужден обращаться к единственному экземпляру... по крайней мере у меня так работает.
Re[9]: Доступ к COM-объекту, который в виде сервиса
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, spy__, Вы писали:
JR>Разница между Vista и предыдущими версиями по части сессий в том, что на Vista нулевая сессия выделена исключительно под сервисы, а ранее она-же была и первой интерактивной. Но сессия — это только верхний, так сказать, уровень. Кроме них есть ещё Window stations, которые отдельно для интерактивного юзера, отдельно для служб, причём для служб их стандартно обычно несколько. Плюс ещё один "водораздел" системы безопасности — связанные со станциями desktops, к которым подключаются потоки. И эти десктопы влияют на, например, пхождение сообщений окнам. Ваши проблемы кроются, видимо, где-то в этих областях, но "ничего не работает" — это слишком расплывчато, да и "удалённая отладка" через форум вряд-ли будет эффективна. Стоит попытаться зацепиться за какую-то конкретную проблему и размотать до конца. Удачи
Да, я понимаю, что в телепата играть очень трудно.
Внесу более конкретное желание: ищу пример, в котором есть сервер COM в виде сервиса, но внутри не простой объект крутится, а составной (например, содержит вложенный мембер, который является COM-объектом). И этот мембер как-то вытаскивается клиентом.
Что значит "убогий"? Мёртвая ссылка? Может просто нужен AddRef?
Писать пример с нуля лениво, вот здесь давно уже валяется пример COM-сервера в службе. Файл comservice2.zip, правда на Delphi. Я добавил в него ещё один объект с интерфейсом, добавил интерфейс с методом, возвращающем этот объект. Реализовал этот интерфейс в тамошних объектах, проверил — всё работает Система WinXP SP3.
Правда, с регистрацией этого добавленного объекта возиться не стал, потому в методе создавал его напрямую, а не через CoCreateInstance, но это вряд-ли могло повлиять — настройки защиты применяются на уровне приложения.
"Нормальные герои всегда идут в обход!"
Re[10]: Доступ к COM-объекту, который в виде сервиса
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, spy__, Вы писали:
JR>Ешё момент, а маршалер для этого ITestCase есть?
Да, там все есть. Я накосячил немного в другом месте из-за невнимательности. Совсем глупо, не создавал объект, а юзал его.
Скачал какой-то пример с codeproject'а, написал к нему, проверил на 2003 винде — все ОК. Правда, сейчас я ловлю access violation, когда пробую обращаться к методам COM-объекта из разных участков приложения. Поток один и тотже. Ковыряюсь.