Could not iterate UPNP services of a device using microsoft UPNP.DLL (C#, Visual Studio 2010)

StackOverflow https://stackoverflow.com/questions/18961733

  •  29-06-2022
  •  | 
  •  

Question

Hi Stack Overflow and sorry for my non-native English level

Currently programming an UPnP discovery service for a project in C# using .NET 4.0 on Visual Studio 2010.

I'm using the official Microsoft UPnP COM API and it's my first time using UPnP. My problem is that I'm trying to iterate on the services of the devices discovered by the library and a COM HRESUT:0X80040500 exception is thrown.

Here is a sample of my code:

IList<UpnpDevice> result = new List<UpnpDevice>();

UPnPDevices upnpDiscoveryResult = m_UPnPFinder.FindByType(upnpType, 0);

var upnpDiscoveryResultEnumerator = upnpDiscoveryResult.GetEnumerator();

while (upnpDiscoveryResultEnumerator.MoveNext())
{
    var upnpDiscoveryDevice = (IUPnPDevice)upnpDiscoveryResultEnumerator.Current;

    UPnPServices services = upnpDiscoveryDevice.Services;
    var allServices = services.GetEnumerator();

    // ------ Exception is thrown just below
    while (allServices.MoveNext())
    {
        UPnPService service = allServices.Current as UPnPService;
        if (service.Id == "urn:schemas-upnp-org:service:WANIPConnection:1")
        {
        }
        else if (service.Id == "urn:schemas-upnp-org:service:WANPPPConnection:1")
        {
        }
    }

I am lost on what to do.

According to these people which I think I may be having the same error...

...the problem may come from the official DLL and I guess I should better use a new one, but I wanted to ask here first. It seems weird to me that such an obvious bug could indeed come from the API.

Était-ce utile?

La solution

I'll answer my own question for posterity, with "UpnpDevice " being a class in my own project.

    /// <summary>
    /// Converts the native class UPnP device to a generic UPnP device.
    /// </summary>
    /// <param name="nativeDevice">The native device.</param>
    /// <returns>
    /// The converted <see cref="UpnpDevice"/>
    /// </returns>
    private UpnpDevice ConvertNativeUPnPDeviceToGenericUpnpDevice(IUPnPDevice nativeDevice)
    {
        UpnpDevice genericDevice = null;

        if (nativeDevice != null)
        {
            IList<UpnpDevice> genericDeviceChildren = new List<UpnpDevice>();
            IList<String> genericDeviceServices = new List<String>();

            // Converting recursively the children of the native device
            if (nativeDevice.HasChildren)
            {
                foreach (IUPnPDevice nativeDeviceChild in nativeDevice.Children)
                {
                    genericDeviceChildren.Add(ConvertNativeUPnPDeviceToGenericUpnpDevice(nativeDeviceChild));
                }
            }

            try
            {
                // Converting the services, it may break on some modems like old Orange Liveboxes thus the try/catch
                foreach (IUPnPService nativeDeviceService in nativeDevice.Services)
                {
                    genericDeviceServices.Add(nativeDeviceService.ServiceTypeIdentifier);
                }
            }
            catch (Exception exception)
            {
                string msg = this.GetType().Name + " - Method ConvertNativeUPnPDeviceToGenericUpnpDevice - Reading the services threw an exception: " + exception.Message;
                m_Logger.Error(msg);
            }

            genericDevice = new UpnpDevice(nativeDevice.UniqueDeviceName,
            nativeDevice.Description,
            nativeDevice.FriendlyName,
            nativeDevice.HasChildren,
            nativeDevice.IsRootDevice,
            nativeDevice.ManufacturerName,
            nativeDevice.ManufacturerURL,
            nativeDevice.ModelName,
            nativeDevice.ModelNumber,
            nativeDevice.ModelURL,
            nativeDevice.PresentationURL,
            nativeDevice.SerialNumber,
            nativeDevice.Type,
            nativeDevice.UPC,
            genericDeviceServices,
            genericDeviceChildren);
        }

        return genericDevice;
    }

Not an exceptionnal answer, but it was the only way for me to get all the services from the device. It will frown on some devices and move on, but at least it'll get all it can without breaking the whole discovery.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top