Невозможно преобразовать COM-объект типа 'System.__ComObject' в тип класса AgentInfo.
У меня есть два C# проекта, один из которых является DLL, а другой является приложением Windows Forms.
У меня есть CoClass, определенный в dll следующим образом
[ComVisible(true),
Guid("1620BE13-A68F-4FA3-B5C8-31092D626CDA"),
ProgId("AgentDLLServer.AgentInfo"),
ClassInterface(ClassInterfaceType.AutoDispatch),
ComSourceInterfaces(typeof(IAgentInfoEvents))
]
public class AgentInfo : _IAgentInfo {}
Он реализует интерфейс _IAgentInfo, который определяется следующим образом
[
ComVisible(true),
Guid("CF803265-AE9D-4308-B790-560FCF63DD4C"),
InterfaceType(ComInterfaceType.InterfaceIsDual)
]
public interface _IAgentInfo{}
Оба определены в DLL, которая успешно зарегистрирована с помощью
regasm /tlb
В другом клиентском приложении Windows на C# я пытаюсь получить доступ к AgentInfo путем приведения объекта, полученного из таблицы запущенных объектов или из другого интерфейса, следующим образом`
_IAgentInfo info =(_IAgentInfo) RotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");`.
где приведенный выше код извлекает объект из ROT или, у меня есть другой интерфейс, полученный из ROT, как определено следующим образом
[
ComVisible(true),
Guid("9B539A5F-5671-48AD-BF9B-7A9AF150CE39"),
InterfaceType(ComInterfaceType.InterfaceIsDual)
]
public interface _IAgentDLLServer
{ AgentInfo GetAgentInfo();}
где я получаю ссылку на интерфейс _IAgentDLLServer из ROT, а затем вызываю на нем метод GetAgentInfo()
`_IAgentDLLServer server= (_IAgentDLLServer)RotNativeMethods.GetObject("BizBrainAgentService.AgentServer") `AgentInfo info=server.GetAgentInfo();
Я могу привести его к _IAgentInfo, но когда я пытаюсь привести возвращенный объект к AgentInfo, выполните следующие действия.
AgentInfo info =(_IAgentInfo) rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");
Я получаю следующую ошибку
Unable to cast COM object of type 'System.__ComObject' to class type 'AgentDLLService.AgentInfo'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Я попробовал следующие решения
а. STAThread для метода main, потому что в сообщении говорилось, что поток, в котором выполнялся этот объект, не имел доступа к информации о типе, как описано в разделе Почему я не могу привести свой COM-объект к интерфейсу, который он реализует в C#?
б. Изменен файл конфигурации приложения следующим образом
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
и версия соответствует, что в InProcServer32 реестра
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{1620BE13-A68F-4FA3-B5C8-31092D626CDA}\InprocServer32\1.0.0.0\RuntimeVersion,
согласно
.NET Framework 4.5 используется по умолчанию, а.NET Framework 3.5 является необязательным . Странный случай System.InvalidCastException ("Невозможно преобразовать COM-объект типа" System.__ComObject "в тип класса System.Windows.Forms.UserControl"), показывающий окно инструментов
с. Я попробовал метод ComImport
[ComImport,
Guid("1620BE13-A68F-4FA3-B5C8-31092D626CDA")]
public class AgentInfo { }
в классе, где я хочу использовать этот объект, в соответствии с методом A Le для вызова COM в C#
д. Двойное приведение объекта
AgentInfo info=(AgentInfo)(объект)rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");
согласно Почему я не могу привести этот интерфейс к конкретному классу?
e Использование оператора as
object obj=rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");
AgentInfo info=obj as AgentInfo
е. Реализация интерфейсов IProvideClassInfo и IProvideClassInfo2 [их импорт с использованием атрибута ComImport] в agentInfoClass
После всех этих попыток я задаюсь вопросом, возможно ли вернуть COM-класс COM из интерфейса COM или из таблицы запущенных объектов в отличие от интерфейса COM.
Кроме того, другой вопрос заключается в том, обрабатывается ли AgentInfo как сетевой тип C# / dot вместо COM-типа, согласно сообщению. Это действительно так? В этом случае приведение не будет выполнено.
Мне известно, что возврат CoClass, а не интерфейса, может быть не очень хорошей практикой, но мне нужно иметь возможность прослушивать события из объекта AgentInfo, а это не представляется возможным из интерфейсов.
1 ответ
Как определяется BizBrainAgentService.AgentInfo? Какие методы AgentInfo вам нужны, а какие нет в _IAgentInfo?
AgentInfo info =(_IAgentInfo) rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");
Похоже, вы приводите BizBrainAgentService.AgentInfo к интерфейсу _IAgentInfo, что будет хорошо, если BizBrainAgentService.AgentInfo его реализует.
Вы не можете привести это обратно к AgentInfo, потому что тип объекта по-прежнему BizBrainAgentService.AgentInfo.
В COM QueryInterface используется для перехода к другому интерфейсу https://docs.microsoft.com/en-us/cpp/atl/queryinterface
Ошибка, которую вы видите, объясняет это -
Unable to cast COM object of type 'System.__ComObject' to class type 'AgentDLLService.AgentInfo'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Поможет ли реализация приемника событий COM с использованием точек подключения?