2012-09-11 5 views
1

Я пытаюсь получить доступ к объектам C# из другого процесса, кроме того, где они находятся через COM. Объекты C# подвергаются воздействию COM.Доступ к объекту C# в outproc COM-сервере из другого процесса на том же компьютере

Проблема заключается в том, что при вызове метода на этих объектах вызовы выполняются локально, а не на COM-сервере outproc, где мне нужны побочные эффекты этих вызовов.

Более точно, вот что я делаю в процессе пытается получить доступ к объектам, проживающим в OutProc COM-сервер:

Type oType = Type.GetTypeFromProgID("myProgId"); 

var obj = Activator.CreateInstance(oType); 

var result = oType.InvokeMember("GetObjForMyClassMethod", 
           BindingFlags.InvokeMethod, null, obj, null); 

Тогда я подаю результат в соответствующий интерфейс (IMyInterface) в C# класса и когда я вызываю методы этого интерфейса, они выполняются удаленно на COM-сервере outproc точно так же, как я ожидаю.

Проблема начинается, когда я использую этот интерфейс для извлечения других объектов C# (я использую метод IMyInterface.GetOtherObject(), который возвращает IOtherObjectInterface).

Когда я делаю вызовы IOtherObjectInterface, они выполняются локально, а не на COM-сервере outproc, поэтому их побочные эффекты теряются (например, если я вызываю метод SetValue, значение не поступает на сервер outproc, и это потерял).

Кроме того, когда я смотрю в отладчике во время выполнения я вижу, что тип интерфейса, для которого удаленной работы вызовов System._ComObject в то время как тип для интерфейса, где удаленные вызовы не работают фактический тип (IOtherObjectInterface) ,

Я попытался повторить все (все атрибуты и другие интерфейсы, реализованные) о том, как IMyInterface (тот, для которого работа удаленных вызовов) подвергается воздействию COM на IOtherObjectInterface (тот, для которого удаленные вызовы не работают), но не повезло.

Что необходимо сделать, чтобы вызовы, которые я делаю на IOtherObjectInterface, выполняются на сервере outproc через RPC, а не в локальном (то есть, где вызывают вызовы), где они никому не нужны?

EDIT:

С тех пор я узнал, что, если я получить объект, для которого он не работает (IOtherObjectInterface), используя тот же метод, который я использую для объекта, для которого он работает (oType. InvokeMember («GetOtherObjForMyClassMethod», ....) он по-прежнему не работает (вызовы, которые я делаю на объекте, по-прежнему не перенаправляются на COM-сервер outproc).

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

Я сильно с uspect, что эта проблема как-то связана с сериализации, хотя оба класса (работает и не работает), кажется, реализовать сериализацию точно так же ...

EDIT2:

Часть я не получаю это факт, что класс, для которого работает этот «COM-удаленный» (тот, для которого я получаю System._ComObject при извлечении объекта за пределами COM-сервера) имеет атрибут «serializable». Я думал, что значение по умолчанию для типов с этим атрибутом было маршалом по значению.

+0

Примечание: Я выяснил, что это не вопрос DCOM, процессы выполняются на одной машине. –

+0

'Я думал, что по умолчанию для типов с этим атрибутом был маршал по значению.' - Да, но вы не маршалируете этот экземпляр (он живет в процессе COM-сервера OOP), вы говорите с его прокси-сервером '__ComObject' по CLR. –

ответ

0

Вы должны использовать ServicedComponent согласно ответу Марка, здесь:

Create Out-Of-Process COM in C#/.Net?

+0

В нем говорится, что это один из вариантов. Как я объяснил выше, он работает для одного класса (без использования ServicedComponent), но не с другим, но я не могу понять разницу между двумя, которые заставляют его работать в одном случае, а не в другом ... – mnrtyrpt123

0

Что вы могли бы сделать, это создать новое приложение в компоненте консоли служб и объявить что это вне процесса приложения , Для этого вам необходимо

  1. Создать новое приложение
  2. правой кнопкой мыши на этом приложении
  3. Перейдите на вкладку «Активация», и выберите «Application Server»
  4. Добавить DLL в это приложение

Возможно, вам придется настроить защиту.

+0

Как я уже сказал, это работает для одного класса, а не другого. Таким образом, проблема заключается не в конфигурации приложения, в котором размещаются эти 2 класса (иначе это вообще не сработало). – mnrtyrpt123

0

Вы подтвердили, я думаю, что IMyInterface.GetOtherObject() выполняет удаленно, и ваш вопрос, почему объект возвращается к вашему вызывающему коду конкретного экземпляра типа .NET реализации IOtherObjectInterface, а не быть System._ComObject или что-то другое, что бы вызывает метод вызова этого объекта, который должен быть удален.

Ответ должен состоять в том, что IMyInterface.GetOtherObject() создает экземпляр «OtherObject», а затем, когда он возвращается, этот экземпляр сортируется по вашему процессу вызова. Это произойдет по умолчанию, если объект имеет сериализуемый тип .NET.

Я думаю, что если бы объект был MarshalByRefObject, он не будет перенаправлен обратно на вызывающий процесс: вызывающий код получит вместо этого TransparentProxy, а затем вызовет его, будет удален, как вы ожидаете.

Оригинальный (IMyInterface) объект является особым случаем, потому что сам вызывающий код создает это, используя Активатор и Тип, полученные из ProgID, с помощью (под капотом) COM Runtime, в результате чего прокси-тип _ComObject.

+0

Прежде всего, спасибо за понимание моего вопроса ;-) Я думал о MarshalByRefObject, но я думаю, что это подразумевает использование удаленных операций, и я понимаю, что эта технология более или менее устарела ... Возможно, мне придется использовать это решение в качестве крайней меры , – mnrtyrpt123

+0

Ну, 'System .__ ComObject' происходит от MarshalByRefObject, поэтому вы уже используете его. Я думаю, что ваше беспокойство о том, что вы используете какую-то устаревшую технологию удаленного доступа, необоснованно. Устранение само по себе устарело в пользу WCF для реализации IPC, но базовая сантехника присутствует в CLR и имеет фундаментальное значение для COM Interop и WCF. –

+0

Дело в том, что я бы хотел использовать MarshalByRefObject через System._ComObject. – mnrtyrpt123