Невозможно преобразовать 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 с использованием точек подключения?

Другие вопросы по тегам