none
MSXMLl 6.0 XmlDOMNodeList fails when is invoked GetEnumerator RRS feed

  • Question

  • Our project uses MSXML 6.0 com object for working with XML through ComImport attribute. Below com Class which provides access to existing MSXML COM(I left only SelectNodes for clarify problem )

    [ComImport]
    [ComSourceInterfaces("MSXML2.XMLDOMDocumentEvents")]
    [TypeLibType(TypeLibTypeFlags.FCanCreate)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("88d96a06-f192-11d4-a65f-0040963251e5")]
    public class FreeThreadedDOMDocumentClass : IXMLDOMDocument2
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x1d)]
        public extern object SelectNodes([In, MarshalAs(UnmanagedType.BStr)] string queryString);
    
    }
    
    [ComImport, Guid("2933BF95-7B36-11D2-B20E-00C04F983E60"), TypeLibType((short)0x10c0)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IXMLDOMDocument2
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x1d)]
        object SelectNodes([In, MarshalAs(UnmanagedType.BStr)] string queryString);
    }
    
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix"), ComImport]
    [Guid("2933BF82-7B36-11D2-B20E-00C04F983E60")]
    [TypeLibType(TypeLibTypeFlags.FDispatchable)]//(short) 0x10c0
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IXMLDOMNodeList: IEnumerable
    {
    
        [DispId(0)]
        IXMLDOMNode this[int index]
        {
          [return: MarshalAs(UnmanagedType.Interface)]
          [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0)]
          get;
        }
    
    
        [DispId(0x4a)]
        int Count
        {
          [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x4a)]
          get;
        }
    }

    And We have problem with some parts of code. Example :

    string xmlText = "<Item> <Element></Element></Item>";
    IXMLDOMDocument2 domDocument = new FreeThreadedDOMDocumentClass();
    domDocument.LoadXml(xmlText);
    string xPath = "//Item";
    IXMLDOMNodeList resultQuery = domDocument.SelectNodes(xPath) as IXMLDOMNodeList;
    resultQuery.GetEnumerator()

    Obtained object resultQuery as result of execution of SelectNodes has problem with GetEnumerator depending on some outside factors:

    1. In windows 7 or more early systems (system without support of WinRT technology)

      • obtained object resultQuery has type System.__ComObject
      • resultQuery.GetEnumerator() executes without any problem and provide working Enumerator
    2. In windows 8 or more later systems (system with support of WinRT technology)

      • obtained object resultQuery has type Windows.Data.Xml.Dom.XmlNodeList. This is WinRt type.
      • resultQuery.GetEnumerator() throws exception:System.ArgumentException: The object's type must not be a Windows Runtime type. I figured out that source of exception is Marshal.GetComObjectData. It means that our Marshalling process fails
    3. In windows 8 or more later systems with version of imported com MSXML 3.0 :

      • obtained object resultQuery has type System.__ComObject
      • resultQuery.GetEnumerator() executes without any problem and provide working Enumerator

    At this moment I found three workarounds for point 2 (using msxml on windows with WinRT) but not the solutions for us (It can be helpful for developers with the same issue):

    1. Do not use foreach and GetEnumerator. it's clear :)
    2. Create custom marshalling for SelectNodes with using ICustomMarshaler which will create wrapper over WinRT type and provide custom GetEnumerator through for.
    3. Change version of msxml from 6 to 3.

    I need help to find source of problem in point 2 and understand how to fix it. Thanks






    MS

    Monday, March 6, 2017 2:04 PM

Answers

All replies