Nicholas Hill
Nicholas Hill

Reputation: 316

How to enable remote communication in a C# Windows Service without IIS?

I'm becoming increasingly baffled by how difficult it is to create a simple Windows Service with a single remotely invocable method using WCF, and then to call that method from a console application.

I can get as far as creating and installing the Windows Service, but can't find any way to allow a console application to communicate with it.

My goals are as follows:

I suppose I can forgo the goal of not having a configuration file if necessary, but I'm pretty determined about the other goals.

Does anyone have any sample code for exposing and consuming the service, beyond pointing me to long and complicated MSDN articles, or books? Your assistance is much appreciated. I promise to eventually read up fully on WCF - all I need is a kick start!

As a point of interest: Are interfaces necessary when defining WCF services? Why are service interfaces so prevelent in WCF example code?

Thanks in advance all,

Nick


Thanks to everyone I managed to put together the following solution!

The following infrastructure exposes the Comms class via WCF inside a Windows Service, without needing a configuration file. Metadata publishing is enabled so that we can add a service reference to the related Console Application tester:

namespace AgentService
    {
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.ServiceProcess;

    [ServiceContract]
    public class Comms
        {
        [OperationContract]
        public string GetStatus() { return "Running"; }
        }

    public class SelfHost<T>
        {

        private ServiceHost host = null;

        public void Start()
            {
            var baseAddress = new Uri("http://localhost:8080/AgentService/");
            host = new ServiceHost(typeof(T), baseAddress);
            var behaviour = new ServiceMetadataBehavior() { HttpGetEnabled = true };
            host.Description.Behaviors.Add(behaviour);
            host.Open();
            }

        public void Stop() { host.Close(); }

        }

    public static class Program
        {

        public static void Main(string[] args)
            {
            if (args.Length > 0)
                {
                var host = new SelfHost<Comms>();
                host.Start();
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
                host.Stop();
                }
            else
                {
                var servicesToRun = new ServiceBase[] { new AgentService() };
                ServiceBase.Run(servicesToRun);
                }
            }

        }

    }

The following class comprises the entirety of the tester Console Application. Again, no configuration files required:

namespace Tester
    {
    using System;
    using System.ServiceModel;
    using Tester.Comms;

    public class Program
        {

        public static void Main(string[] args)
            {
            var comms = new CommsClient(new BasicHttpBinding(),
                                        new EndpointAddress("http://localhost:8080/AgentService/"));
            Console.WriteLine(comms.GetStatus());
            Console.ReadKey();
            }

        }

    }

Thanks for all the help.

Upvotes: 0

Views: 2154

Answers (1)

Related Questions