2

For an application, we use UPnP to discover and register devices/service(we have server and client part).

For the discovery, we used the http://managedupnp.codeplex.com/ which worked very well.

To register, we did found some library, but they were VERY buggy(intel open source library), and we now want to use the COM component and make a small c# abstraction on it.

I found some documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/aa381805(v=vs.85).aspx but I've got a problem.

This library contains only interfaces, and I can't see how I can get an instance of it. And I can't find any example/documentation.

So, does anybody knows how to register a device/service with this COM component?

Thank you!

EDIT:

I tried to generate a C# dll:

midl /target NT51 /tlb "C:\upnphost.tlb" "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\upnphost.idl"
tlbimp upnphost.tlb

But after importing this generated dll, I only got the same interface than before :/. Am I on the right way, how should I do that?

J4N
  • 19,480
  • 39
  • 187
  • 340
  • The coclass is UPnPRegistrar, clsid 204810b9-73b2-11d4-bf42-00b0d0118b56. You'll find this rough going in C#, there is no type library for it. This is really only designed to be used from C++ code. It is technically possible by writing your own [ComImport] version of the interfaces and coclass. The SDK declarations are in upnphost.idl. Best to do this in C++/CLI. – Hans Passant Feb 01 '13 at 11:56
  • @HansPassant It's not an option for my enterprise :(, and the client class is available directly in c# with managed code, no? What are my options to use it in c#? – J4N Feb 01 '13 at 12:03
  • SO isn't a very good place to ask questions when you are not allowed to write code. Hire a contractor, I guess. – Hans Passant Feb 01 '13 at 12:19
  • @HansPassant ?? I'm allowed, but not in c++, I've to do it in c# – J4N Feb 01 '13 at 12:30
  • Any way to do some ComImport(or generated them once?) – J4N Feb 01 '13 at 12:39
  • Rather than write bindings for a C++ library, you could use a third party C# library. [This previous question](http://stackoverflow.com/q/1801134/311966) lists a number of libraries that are far better maintained than the old Intel code. Some of these are liberally licensed and free to use in any commercial context. I obviously have a bias towards [ohNet](http://www.openhome.org/wiki/OhNet) which I can say for sure is free and actively maintained. – simonc Feb 02 '13 at 12:08
  • @simonc : upnp.dll is only for the client side, Mono.upnp seems not maintened. We are currently using the intel version, and we encounter a lot of bugs, we don't want this anymore. I never heard of OhNet, I will take a look – J4N Feb 03 '13 at 11:01
  • @simonc : Can we find somewhere complete example of usage of OhNet, to have the code doc is one thing, but if we don't know which class we should use, is another problem. I saw the `CpDeviceListUpnpAll` class, but I can't just "start" the discovery, I need to refresh manually the search – J4N Feb 05 '13 at 06:46
  • @J4N See [TestProxyCs](https://github.com/openhome/ohNet/blob/master/OpenHome/Net/Bindings/Cs/ControlPoint/Tests/TestProxy.cs) for an example control point app. You can refresh a device list using the `Refresh()` function (available in the [CpDeviceList](https://github.com/openhome/ohNet/blob/master/OpenHome/Net/Bindings/Cs/ControlPoint/CpDevice.cs) base class) – simonc Feb 05 '13 at 07:50
  • @simonc : To the search is initiated in the constructor? I posted some question on the forum: http://forums.openhome.org/showthread.php?tid=1094 – J4N Feb 05 '13 at 08:05

1 Answers1

2

Once you've done the midl + tlbimp, you can just write this kind of code, as the tlbimp should have create a class (UPnPRegistrarClass) and an interface IUPnPRegistrar that the underlying COM class implements:

IUPnPRegistrar registrar = (IUPnPRegistrar)new UPnPRegistrarClass();
registrar.RegisterDevice(
    File.ReadAllText("DimmerDevice-Desc.xml"),
    "My.Class",
    "MyInitString",
    "MyContainerId",
    Path.GetFullPath("."),
    3200);

Note: for this to work, download the UPnP device registration sample on your disk, and copy the two XML description files to the current execution path. You also must implement a COM Object with a progid ("My.Class" that works because the RegisterDevice call will indeed instantiate this object to build an identifier. You can do that with .NET.

Device and service description formats are available here: UPnP™ Device Architecture 1.1. In the Windows world, there are some extra restrictions specified here: Creating a Device Description (Windows)

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • If I do this, I got exactly the same result than if I use the class/interfaces available with UPnPLibHost. And I get this exception: `Interop type 'UPnPHostLib.UPnPRegistrarClass' cannot be embedded. Use the applicable interface instead. ` – J4N Feb 05 '13 at 14:10
  • 1
    For this error, just go to the UPnPHostLib Reference in VS Solution Explorer, press F4 (Properties) and set the 'Embed Interop Types' property to 'False'. You didn't mention 'UPnPLibHost'. What's this? – Simon Mourier Feb 05 '13 at 15:44
  • Seems to work, but do you have an example of XML I should put here? To declare a device + one action? Because I tried and got some exception (FileNotFoundException) – J4N Feb 06 '13 at 09:25
  • 1
    Well, you're supposed to be able to define that yourself, since you want to register a device :-) Consult UPnP documentation. Samples are provided here: http://upnp.org/sdcps-and-certification/standards/sdcps/ – Simon Mourier Feb 06 '13 at 09:47
  • Yeah, but in my case, it's not a multimedia device, so it doesn't fit any of these category. The Basic device has just a ``, which doesn't help me a lot. I tried to create my own, but I'm missing something. Is there a tools to generate those xml file? And there is additional parameter(other than the XML), which I'm not sure to understand what they are for. – J4N Feb 06 '13 at 11:29
  • And I don't understand what are those path we have to specify, are those HTTP path? Local system path? Are we obligated to create file on the disk? – J4N Feb 06 '13 at 11:41
  • In fact, I found on what I was blocking: The DeviceControl I was specifying(My.Class), need to implement the `ComVisible(true)` and `ClassInterface(ClassInterfaceType.AutoDual)` and register for COM interop in the build tab of the class library project. But now I don't know what this DeviceControl should return for an object? – J4N Feb 07 '13 at 07:34
  • I'm closing this because the original question is answered and you really deserve to be rewarded for that, but my global problem isn't solved yet and I would appreciate if you could look an eye on the current problem? http://stackoverflow.com/questions/14746725/upnp-declare-a-service-on-upnp-using-com – J4N Feb 07 '13 at 08:33