microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.84k stars 320 forks source link

Add DNS-SD API #281

Closed ePirat closed 3 years ago

ePirat commented 4 years ago

Proposal: Add a DNS-SD discovery and announcement API

Summary

Windows 10 added support for DNS-SD a while ago, but its not really usable in most apps as there is no API to discover and announce services that is usable for Win32 apps.

Rationale

Scope

Capability Priority
This proposal will allow developers to discover services using DNS-SD Must
This proposal will allow developers to announce services using DNS-SD Must
This proposal will allow developers to discovery/announce services using other means of autodiscovery Could

Important Notes

Proposing an API seems a bit premature here, as there are decisions to make for this: Should the API be specific for DNS-SD? Should it allow handling other discovery mechanisms (at the cost of ease of use/simplicity of the API)? How to abstract the ability to set/read additional service metadata (via TXT record) in the API?

Open Questions

The main issue would be how to handle lack of DNS-SD on older Windows 10 versions that are supported by Project Reunion.

jonwis commented 3 years ago

Check out DnsServiceBrowse and DnsServiceRegister for use with at least Windows 10. Those are supposed to work in Win32 apps, and if they don't we'd like to hear details (and sample code!) about it.

What else would you want support-wise?

ePirat commented 3 years ago

Hi, thanks a lot, I had no idea this API exists! (For whatever reason its nearly impossible to find, I was only able to find the WinRT APIs for this, would help to maybe have a link to this API on the DNS-SD WinRT API docs)

stevewhims commented 3 years ago

Hi, @ePirat, FYI there are now links to the Win32 API topics from the Windows.Networking.ServiceDiscovery.Dnssd namespace topic, and from the type topics within there (for example, DnssdRegistrationResult).

Thanks! Steve

ePirat commented 3 years ago

Thanks! After looking at the API, I am wondering about the version in DNS_SERVICE_BROWSE_REQUEST, the documentation mentions DNS_QUERY_REQUEST_VERSION2 for it but it seems its not actually present in the SDK headers? Additionally the documentation makes no mention about the exact Windows 10 version since when the DNS_QUERY_REQUEST_VERSION2 would be available or not, so I am wondering whats the proper way to check if version 1 or 2 can be used?

I suspect I can always assume at least DNS_QUERY_REQUEST_VERSION1 is usable when the DnsServiceBrowse function exists?

jonwis commented 3 years ago

Ok - an update that makes the VERSION2 tag available in the SDK is coming. Internal folks, track http://task.ms/30284268 ... for now, you can manually add it to your pch.h or any other common spot, and remove it when a new SDK is released:

#define DNS_QUERY_REQUEST_VERSION2  0x2

You're right that there's no easy way to determine whether VERSION2 is available. A little source archaeology suggests that it's available on at least Windows 10's initial release. Our API design guidelines have evolved since then so you can detect these "versioned structs" more easily.

ePirat commented 3 years ago

After further playing around with the API and working on a very simple prototype, it turns out the API is incredibly useless unfortunately as it is so low level that using it is really really hard.

Additionally it seems to just not work reliably at all. With a started discovery session, whenever a new device is announced during the running session, the callback is never called for the added device. Interestingly, the callback is called once the device is removed again during an active session (callback called with a result with TTL of 0, which according to how I understood the related RFC means removal of the device). But the device was never added in the first place.

Given it is so hard to use the API and that it does not even work properly, it does not seem sufficient at all to get Apps to adopt native DNS-SD on Windows. Using something like Apples Bonjour Service + DNS-SD API is far far simpler and actually works, contrary to the DnsServiceBrowse API, from what I can tell.

Of course it could be I am just using the API wrong, given how low level it is. But then again, the documentation does an incredibly poor job detailing how it is supposed to be used.

joaopedrolourencoaffonso commented 3 years ago

Does anyone know a good Python library to implement this on windows (10)?

sebastianhaberey commented 2 years ago

@ePirat I remember I found your comment above before I implemented my plugin. It was a bit disheartening, but I decided to see for myself.

Since I have used the DNS-SD APIs on macOS / iOS, Android and this one here, I think I can safely say I agree about the "low-level" aspect of the API. It feels incredibly old school and there is a lot of guesswork involved - especially for developers that don't deal with low-level Windows APIs every day.

On the other hand, I disagree about the reliability - once I figured out the details, it has been working well for me. The project has automatic tests for service registration, service unregistration, start discovery and stop discovery and they pass every time.

This class in my plugin handles all the Windows DNS-SD API calls and may be of help for anybody looking for a usage example in the future.

ePirat commented 1 year ago

@sebastianhaberey Thanks for posting this, I will have another look at this. The specific case that did not work reliably for me was when discovering _services._dns-sd._udp.local to get all service types, but maybe I made a mistake somewhere in the logic of that code…