Connecting via named pipe from windows service (session#0) to desktop app (session #1)

不羁岁月 提交于 2019-11-27 08:09:13

An easier solution might be to use a WCF duplex contract with the Windows service hosting the WCF service. The client App would call an operation on the service to register itself, when it starts up. The Ping would then be an operation invoked periodically by the service on the client's callback contract, to which the App would respond.

Service visibility works this way round, because the Windows service can run with SeCreateGlobalPrivilege, and so the shared memory object via which the pipe name is published by the service can be created in the Global kernel namespace, visible to other sessions. Interactive applications can't easily get that privilege in Windows7, so WCF services in such applications fall back to publishing the pipe in the Local kernel namespace, visible only within their own session.

Finally I've found a solution - using Named Pipes from System.IO.Pipes directly. It's seems that WCF's pipes support implementation doesn't use System.IO.Pipes.

Server:

using (var pipeServer = new NamedPipeServerStream("mypipe", PipeDirection.Out, 1))
{
    try
    {
        while (true)
        {
            // #1 Connect:
            try
            {
                pipeServer.WaitForConnection();
            }
            catch (ObjectDisposedException)
            {
                yield break;
            }
            if (ae.IsCanceled())
                return;

            // #2: Sending response:
            var response = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
            try
            {
                pipeServer.Write(response, 0, response.Length);
            }
            catch (ObjectDisposedException)
            {
                return;
            }

            // #3: Disconnect:
            pipeServer.Disconnect();
        }
    }
    finally
    {
        if (pipeServer.IsConnected)
            pipeServer.Disconnect();
    }
}

Client:

using (var pipeClient = new NamedPipeClientStream(".", "mypipe", PipeDirection.In))
{
    try
    {
        try
        {
            pipeClient.Connect(TIMEOUT);
        }
        catch(TimeoutException ex)
        {
            // nobody answers to us
            continue;
        }
        using (var sr = new StreamReader(pipeClient))
        {
            string temp;
            while ((temp = sr.ReadLine()) != null)
            {
                // got response
            }
        }
    }
    catch(Exception ex)
    {
        // pipe error
        throw;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!