I am developing a program that uses Bonjour algorithm to find services in network. I downloaded Bonjour SDK for Windows. There were two sample applications on .Net. Both are Windows Forms project. Samples work fine but when I tried to implement sample console application I received AccessViolationException. Here is my code:
class Program
{
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
//next line raises AccessViolationException
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Console.ReadKey();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
I found the solution - all methods from Bonjour library should be called from STA thread. So I added [STAThread] attribute to Main method. The code now looks like this:
class Program
{
[STAThread]
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Console.ReadKey();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
I solved the issue with AccessViolationException but received a new one. After I call method Browse, 'ServiceFound' event should be called for each service defined in network. But it did not. After some time of investigation I found that I need to run message pump to receive all these events. So the final code looks like this:
class Program
{
[STAThread]
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Application.Run();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
To stop message loop call Application.Exit().