简体   繁体   中英

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:

  • Allow a Windows Service to self host a WCF service exposing a single method, regardless of what machine it is installed onto.
  • Want a console application to be able to invoke that method on a machine whose name is entered by the user.
  • Don't want to require the presence of IIS.
  • Want to have a clean, simple, short solution. Bonus points for a single page of code or less.
  • No pesky overengineered configuration file.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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