Com + поздняя привязка c # 4.0 - PullRequest
9 голосов
/ 14 апреля 2011

В моей программе я создаю объекты Com + динамически (с поздним связыванием), используя

Type comObjectType = Type.GetTypeFromProgID(progId, true); 
object comObject = Activator.CreateInstance(comObjectType); 

А затем вызвать один из методов, используя отражение

object result = comObjectType.InvokeMember(MethodToActivate, BindingFlags.InvokeMethod, null, comObjec, new object[] {....});

Отлично работает в .Net 1.1 / 2.0 / 3.5

Теперь я пытаюсь запустить такой же код на той же машине (Windows XP), скомпилированной для .Net 4.0, но у меня есть

Exception: Method 'System.__ComObject.{MethodName}' not found. 

У меня есть исключение для большинства объектов Com + (не для всех). Кто-нибудь знает в чем проблема? Почему я получаю исключение в среде FW 4.0? Что я должен сделать, чтобы избежать этого?

Большое спасибо, Daniel

После еще одного исследования я обнаружил, что некоторые прокси Com + создаются как System._ComObject (это, я полагаю, нативные), а некоторые создаются как System.Runtime.Remoting.Proxies._TransparentProxy (я думаю, что это .Net Com + объекты). Вызов метода отлично работает для тех, кто создан как System._ComObject и не работает для System.Runtime.Remoting.Proxies._TransparentProxy. Наиболее интересным является тот факт, что в .Net 2.0 все объекты создаются одинаково (_ComObject и _TransparentProxy), но вызов метода работает нормально. Еще одним интересным фактом является то, что я вижу «отсутствующий» метод в отладчике с использованием refleon

((System.EnterpriseServices.RemoteServicedComponentProxy)((((System.Runtime.Remoting.Proxies.__TransparentProxy)(ObjectToActivate)))._rp)).ProxiedType.GetMethods()

Некоторое время я думал, что это может быть проблемой безопасности, но я запускаю код, когда WindowsService вошел в систему как пользователь с правами администратора

Ответы [ 2 ]

7 голосов
/ 27 апреля 2011

Я обнаружил, что существует разница между .NET FW в создании COM-типов, и, насколько я понимаю, разница существует только для COM-объектов .NET. Когда тип объекта COM создается с

Type comObjectType = Type.GetTypeFromProgID(progId, true);

тип, возвращаемый в .NET 1.1 / 2.0 / 3.5, является фактическим .NET-типом объекта, поэтому при вызове его метода проблем не возникает, но в .NET 4.0 тип System.__ComObject возвращается, поэтому код

result = comObjectType.InvokeMember(
   MethodToActivate, BindingFlags.InvokeMethod, null, ObjectToActivate, InputParams);

завершается с ошибкой метода не найден.

Решение, которое я нашел, следующее:

Type comObjectType = Type.GetTypeFromProgID(progId, true);        
object comObject = Activator.CreateInstance(comObjectType);

// here the real object type is returned
Type acctualObjectType = comObject.GetType();
result = acctualObjectType.InvokeMember(
   "MethodToActivate", BindingFlags.InvokeMethod, null, comObject, InputParams);

Этот код отлично работает для всех сред.

1 голос
/ 27 апреля 2011

Я не уверен, почему ваш ранее запущенный код больше не работает, однако я считаю, что в .Net 4.0 вы можете вызывать COM-методы, используя привязку IDispatch / late через тип dynamic - см. Поддерживает ли C # .NETIDispatch позднего связывания? .

...