Send string commands or bytes to a Windows Service? (When running)

后端 未结 4 1284
予麋鹿
予麋鹿 2021-02-10 22:41

Is there any way to give string or byte array commands to a Windows Service? (When running)

4条回答
  •  情歌与酒
    2021-02-10 22:47

    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:

    1. Should any computer be able to send this request to the service, or just the local machine?
    2. Should any user be able to send this request, or just specific users/roles?
    3. If the message contents is seen by other users is this a potential security violation?
    4. Does the service need to acknowledge the message or send a response?
    5. Does the message need to be tamper proof?
    6. How many processes/threads will be sending messages at the service at a time?

    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:

    1. .Net Remoting - Easy, but has security & reliability issues.
    2. WCF Services - (.Net 3 or above) Easy to code, not entirely robust under heavy loads.
    3. Sockets - Hard to code, difficult to get right, but can be made to work.
    4. DCOM - Hosting a COM object in your .Net process and allow Windows to marshal the call.
    5. Win32 RPC - Raw Win32 libraries exist in C#, or you can write your own.

    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);
    }
    

提交回复
热议问题