简体   繁体   English

无法使用Microsoft UPNP.DLL(C#,Visual Studio 2010)迭代设备的UPNP服务

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

Hi Stack Overflow and sorry for my non-native English level 嗨,Stack Overflow,对于我的非母语英语水平感到抱歉

Currently programming an UPnP discovery service for a project in C# using .NET 4.0 on Visual Studio 2010. 当前在Visual Studio 2010上使用.NET 4.0在C#中为项目编程UPnP发现服务。

I'm using the official Microsoft UPnP COM API and it's my first time using UPnP. 我正在使用官方的Microsoft UPnP COM API,这是我第一次使用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. 我的问题是,我试图对库发现的设备的服务进行迭代,并且抛出COM HRESUT:0X80040500异常。

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. ...问题可能来自官方DLL,我想我最好使用一个新的DLL,但我想先在这里问一下。 It seems weird to me that such an obvious bug could indeed come from the API. 在我看来,如此明显的错误确实可能来自API。

I'll answer my own question for posterity, with "UpnpDevice " being a class in my own project. 我将回答我的后代问题,“ UpnpDevice”是我自己项目中的一个类。

    /// <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. 它会在某些设备上皱眉然后继续前进,但是至少它将获得所有功能,而不会破坏整个发现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM