Is there any way to give string or byte array commands to a Windows Service? (When running)
You need some form of IPC (Inter-Process Communication). Which one you choose can depend greatly upon what you want to allow, and what you don't want to allow. For instance you need to consider the following:
As you can see, there are just a host of issues you open up when you introduce IPC. Consider the questions above and research the following possible solutions:
All of these have ups and downs, pros and cons. It really depends what your specific needs are.
Since you indicated your trying to call the service from the local machine, the easiest way is to either use WCF over Named Pipes (which attempts to limit communications to the local machine). If you just want to transport binary data in and out of the service then the RPC libarary linked above will work fine.
The following example demonstrates using the above RPC library:
Put this in your service:
Guid iid = new Guid("{....}");
using (RpcServerApi server = new RpcServerApi(iid))
{
server.OnExecute +=
delegate(IRpcClientInfo client, byte[] arg)
{
byte[] response;
//do whatever
return response;
};
server.AddProtocol(RpcProtseq.ncalrpc, "MyServiceName", 5);
server.AddAuthentication(RpcAuthentication.RPC_C_AUTHN_WINNT);
server.StartListening();
...
And here is the client code:
Guid iid = new Guid("{....}");
using (RpcClientApi client = new RpcClientApi(iid, RpcProtseq.ncalrpc, null, "MyServiceName"))
{
client.AuthenticateAs(null, RpcClientApi.Self, RpcProtectionLevel.RPC_C_PROTECT_LEVEL_PKT_PRIVACY, RpcAuthentication.RPC_C_AUTHN_WINNT);
byte[] input, output;
output = client.Execute(input);
}
As @Derrick mentioned, .Start()
can be used, which can also accept arguments that can be passed to the service (but this is at run-time not during execution).
If you're looking to pass information while the service is executing you have a few options:
There are inevitably more, but those are what I can think of off the top of my head.
You can send start, restart and stop commands to the service, and I belive you can execute other defined commands as well.
Here is an example of programatically starting a registered service called "myService"
using System.ServiceProcess;
//...
System.ServiceProcess.ServiceController Service;
Service = new ServiceController("myService");
if (Service != null && Service.Status == ServiceControllerStatus.Stopped)
Service.Start();
//...
Look in SeviceController. You are probably looking for:
// // Summary: // Executes a custom command on the service. // public void ExecuteCommand(int command);
It's my understanding though that these commands need to be predefined. You cannot pass arbrary commands to the services, i.e., this is not a method of passing data.
I will sometimes host a WCF service within a Windows service for the purpose of controlling the behavior of the service at runtime.
If you really just want to send raw data to the service and you don't want to deal with configuring a WCF service (which really isn't that difficult to do, by the way), you could probably accomplish that using Named Pipes or by listening for socket connections on some port.