如何在C#中强制转换IDispatch

时间:2017-04-20 07:02:24

标签: c# com msxml

我一直在用c#开发一个web服务,将网站与本地数据库链接起来。用于本地应用程序的SDK是COM对象。第二天,我打算如何将下面的VB代码(在SDK协议中给出)转换为C#等价物:

XML_DOM := CreateOleObject('MSXML2.DOMDocument.3.0') as IXMLDOMDocumen
GetData(XML_DOM as Idispatch)

我试过这个:

System.Type objType = System.Type.GetTypeFromProgID("PERCo_S20_SDK.ExchangeMain");
            dynamic comObject = System.Activator.CreateInstance(objType);
            if (comObject.SetConnect("192.168.1.14", "211", "ADMIN", "") != 0)
            {
                    //Could not connect to server!
            }
            XmlDocument dep_xml = new XmlDocument();
            XmlDeclaration dep_xml_decl = dep_xml.CreateXmlDeclaration("1.0", "UTF-8", "yes");
            XmlElement root = dep_xml.DocumentElement;
            dep_xml.InsertBefore(dep_xml_decl, root);
            XmlElement element = dep_xml.CreateElement(string.Empty, "documentrequest", string.Empty);
            element.SetAttribute("type", "subdiv");
            dep_xml.AppendChild(element);
            comObject.GetData(dep_xml as IDispatch);
            comObject.Disconnect();

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
        private interface IDispatch
        {
            [PreserveSig]
            int GetTypeInfoCount(out int Count);

            [PreserveSig]
            int GetTypeInfo
            (
              [MarshalAs(UnmanagedType.U4)] int iTInfo,
              [MarshalAs(UnmanagedType.U4)] int lcid,
              out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo
            );

            [PreserveSig]
            int GetIDsOfNames
            (
              ref Guid riid,
              [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)]
                string[] rgsNames,
              int cNames,
              int lcid,
              [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
            );

            [PreserveSig]
            int Invoke
            (
              int dispIdMember,
              ref Guid riid,
              uint lcid,
              ushort wFlags,
              ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
              out object pVarResult,
              ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
              out UInt32 pArgErr
            );
        }

但我收到错误

An exception of type 'System.ArgumentException' occurred in System.Dynamic.dll but was not handled in user code

Additional information: Could not convert argument 0 for call to GetData.

请帮助我如何在C#中投射IDispatch。

1 个答案:

答案 0 :(得分:1)

  

System.Dynamic.dll中出现“System.ArgumentException”类型的异常,但未在用户代码中处理

     

其他信息:无法将参数0转换为 GetData

你的问题在这里:

 XmlDocument dep_xml = ...
 comObject.GetData(dep_xml as IDispatch);  // <------ BANG!!

XmlDocument不是标准的 OLE自动化/调度类型。它不是:

  • int
  • float
  • char
  • BSTR
  • SAFEARRAY
  • etc

...或公开IDispatch的对象,XmlDocument未实现的COM接口。 XmlDocument需要[ComVisible]出席。

如果对象符合COM标准,那么您可以:

 comObject.SomethingOrOther(myComCompliantObject);

......没有不必要的演员。