How to communicate with a windows service?

61,642

Solution 1

I could successfully handle the (almost) same issue as yours doing the following:

In your Class : ServiceBase, that represents your Service class, you might have:

public Class () //constructor, to create your log repository
    {
      InitializeComponent();

      if (!System.Diagnostics.EventLog.SourceExists("YOURSource"))
      {
        System.Diagnostics.EventLog.CreateEventSource(
           "YOURSource", "YOURLog");
      }
      eventLog1.Source = "YOURSource";
      eventLog1.Log = "YOURLog";
    }

Now, implement:

protected override void OnStart(string[] args)
{...}

AND

protected override void OnStop()
{...}

To handle custom commands calls:

protected override void OnCustomCommand(int command)
    {
      switch (command)
      {
        case 128:
          eventLog1.WriteEntry("Command " + command + " successfully called.");
          break;
        default:
          break;
      }
    }

Now, use this in the application where you'll call the Windows Service:

Enum to reference your methods: (remember, Services custom methods always receive an int32 (128 to 255) as parameters and using Enum you make it easier to remember and control your methods

private enum YourMethods
  {
    methodX = 128
  };

To call a specific method:

ServiceController sc = new ServiceController("YOURServiceName", Environment.MachineName);
ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "YOURServiceName");//this will grant permission to access the Service
    scp.Assert();
    sc.Refresh();

    sc.ExecuteCommand((int)YourMethods.methodX);

Doing this, you can control your service.

Here you can check how to create and install a Windows Service. More about the ExecuteCommand method.

Good luck!

Solution 2

If you are using .Net Framework 4, then memory mapped files provide a fairly easy way of implementing cross process communication.

It is fairly simple, and well described in documentation, and avoids the overhead (at runtime but also in terms of development effort) of using WCF or other connection/remoting based interactions, or of writing shared data to a central location and polling (database, file, etc).

See here for an overview.

Solution 3

You could accomplish this very easily by making the service host a WCF service and connecting to it from your application.

Solution 4

We use Named pipes for this purpose. But our client implemented with C++. If your service and application are implemented in .Net, you can use .Net remoting.

Solution 5

In older versions of Windows, you could configure your Windows service to interact with the desktop. This allowed you to add user interface elements directly to your service that could be presented to the user. Beginning with Windows Vista, services can no longer interact directly with users, i.e., no user interfaces.

To do this, what you want to do is write your Windows service and a front-end Windows application. To provide the communication bridge between the two, I would strongly recommend using Windows Communication Foundation (WCF).

To create a C# Windows service, you can follow the step-by-step instructions here.

Share:
61,642
Alexandru Pupsa
Author by

Alexandru Pupsa

Updated on December 21, 2020

Comments

  • Alexandru Pupsa
    Alexandru Pupsa over 3 years

    I want to create a windows service that validates data and access it from another windows application, but I'm new to services and I'm not sure how to start.

    So, while the service is running, a windows application should somehow connect to the service, send some data and get a response, true or false.

  • Matt Davis
    Matt Davis over 13 years
    .NET Remoting has been superseded by WCF.
  • Rob Levine
    Rob Levine over 13 years
    This may work, but there are a host of security implications to consider when doing this. You now have a service with an open port listening - how can you validate who is connecting? Are you protected against malicious connections? You may need to escalate permissions to NETWORK SERVICE or somesuch just to open the connection, whereas your service may not require this level of permission. Overall - I'd think carefully before implementing this if there are other, simpler, safer options.
  • Rob Levine
    Rob Levine over 13 years
    @Matt Davis - that it just isn't true for all remoting usage scenarios. There is no WCF equivalent of binary remoting a MarshalByRefObject object in WCF (which would potenitally be the best remoting solution to this problem). WCF superceds remoting for many use cases but not all.
  • Jeff LaFay
    Jeff LaFay over 13 years
    @Rob, you don't have to make the service listen on a tcp port. WCF can use named pipes for communication between applications on the same machine. Of course if the desktop application is on another machine, you would have to have an open port but I don't think that's the case for this scenario.
  • Rob Levine
    Rob Levine over 13 years
    @jlafay - fair point about named pipes - you are right, but for any connection oriented approach you will have a host of security implications to consider.
  • Matt Davis
    Matt Davis over 13 years
    @Rob Levine, while it is true there is no equivalent for the MarshalByRefObject scenario within WCF, there are still ways around this within a WCF framework. The MSDN website specifically says that .NET Remoting is a legacy technology maintained for backward compatibility and not recommended for new development. msdn.microsoft.com/en-us/library/kwdt6w2k.aspx
  • Matt Davis
    Matt Davis over 13 years
    Even within the NetTcpBinding you can use the localhost address to limit access to the local machine. While security implications do arise once you cross the machine boundary, the fact remains that WCF makes distributed operation possible while a memory mapped solution precludes it.
  • Rob Levine
    Rob Levine over 13 years
    @Matt Davis - Certainly for distributed applications WCF is the way forward, and this is what most people want to do with remoting. Even though the original remoting is considered legacy, I would still maintain there is a subset of functionality that cannot easily be replicated in WCF, and so WCF is not a replacement for. I'd be interested to know what you have in mind for "ways around" the lack of a MarhsalByRefObject (i.e. by reference semantics) remoting client, because the few times I've needed it, I've never found the equivalent. Having said that, I may be missing something.
  • Matt Davis
    Matt Davis over 13 years
  • Matt Davis
    Matt Davis over 13 years
    @Rob Levine - Don't get me wrong. I use .NET Remoting in my current project because doing the equivalent in WCF just feels heavyweight. Still, Microsoft's official position is that WCF should be used for new development, even when the "distributed" operation simply means crossing AppDomains in the same process.
  • Rob Levine
    Rob Levine over 13 years
    @Matt Davis - thanks for the link - very much appreciated. I'll be looking through that in more detail, but it seems this is showing how to get similar client-activated "by reference" behaviour in WCF - which I genuinely didn't know could be done. I shall play aournd later, but thanks again.
  • Rolf
    Rolf over 4 years
    Sniffing the event log to transfer business data between application components is perhaps not the worst idea ever, but it comes close.
  • mrid
    mrid almost 4 years
    Is there a way I can send something other than an int, say a string to the service? And how can I get a return value ( sent by the service) in my application
  • Mike Lowery
    Mike Lowery almost 4 years
    @MattDavis And 10 years later, WCF is now superseded by gRPC.
  • Ondra Starenko
    Ondra Starenko over 3 years
    @mrid I'm afraid that is not possible when you you this way of communication