none
Named Pipe Communication Between Windows Service And GUI RRS feed

  • Question

  • Hello there!

    I have two application windows service and window form (GUI). I am controlling windows service from GUI. Once I start service from GUI then: 

    for example there is a loop from 0 to 10;

    And in this loop service sending message to GUI, which will be showing in label or textbox in GUI.

    BUT, the issue is it sending message for first time (when counter is 0) only not next time and throwing error "Access to the path is denied."...

    GUI has a class:

                    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.IO.Pipes;
    using System.Diagnostics;

    namespace GUI
    {
        // Delegate for passing received message back to caller
        public delegate void DelegateMessage(string Reply);

        class PipeServer
        {
            public event DelegateMessage PipeMessage;
            string _pipeName;

            public void Listen(string PipeName)
            {
                try
                {
                    // Set to class level var so we can re-use in the async callback method
                    _pipeName = PipeName;
                    // Create the new async pipe 

                    PipeSecurity _pipeSecurity = new PipeSecurity();
                    PipeAccessRule psEveryone = new PipeAccessRule("Everyone", PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Allow);

                   _pipeSecurity.AddAccessRule(psEveryone);

                    NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName,
                                       PipeDirection.In, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 4, 4, _pipeSecurity);

                    // Wait for a connection
                    pipeServer.BeginWaitForConnection
                    (new AsyncCallback(WaitForConnectionCallBack), pipeServer);
                }
                catch (Exception oEX)
                {
                    Debug.WriteLine(oEX.Message);
                }
            }

            private void WaitForConnectionCallBack(IAsyncResult iar)
            {
                try
                {
                    // Get the pipe
                    NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState;
                    // End waiting for the connection
                    pipeServer.EndWaitForConnection(iar);

                    byte[] buffer = new byte[10000];

                    // Read the incoming message
                    pipeServer.Read(buffer, 0, buffer.Length);

                    // Convert byte buffer to string
                    string stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    Debug.WriteLine(stringData + Environment.NewLine);

                    // Pass message back to calling form
                    PipeMessage.Invoke(stringData);

                    // Kill original sever and create new wait server
                    pipeServer.Close();
                    pipeServer = null;
                    pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

                    // Recursively wait for the connection again and again....
                    pipeServer.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), pipeServer);
                }
                catch
                {
                    return;
                }
            }
        }
    }

    And on form1:  It contains only a textbox for showing logs

                        

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;
    using System.ServiceProcess;
    using System.Diagnostics;
    using System.Reflection;
    using System.Security.Principal;


    namespace GUI
    {
        public partial class frmStartService: Form
        {

            EventLog eventLog = new EventLog();
            Timer timer1;

            public delegate void NewMessageDelegate(string NewMessage);
            private PipeServer _pipeServer;

            public frmStartService()
            {
                InitializeComponent();
                eventLog.Source = "TESTIT";
                lblErrorMsg.Text = string.Empty;

                _pipeServer = new PipeServer();
                _pipeServer.PipeMessage += new DelegateMessage(PipesMessageHandler);
            }


            private void FGMConfiguration_Load(object sender, EventArgs e)
            {

       ServiceController sc;
                sc = new ServiceController("WCFTEST", Environment.MachineName);

                sc.Start();

                _pipeServer.Listen("TestPipe");

                txtMessage.Text = "...";

            }

            private void PipesMessageHandler(string message)
            {
                try
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new NewMessageDelegate(PipesMessageHandler), message);
                    }
                    else
                    {
                        txtLogs.Text += Environment.NewLine + message;
                    }
                }
                catch (Exception ex)
                {

                    Debug.WriteLine(ex.Message);
                }

            }

        }

    }

    ============  Create a windows service ==== And Installer name would be any thing make sure you are calling correct service form this GUI.               WIndows service has this class:

                                   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.Diagnostics;
    using System.IO.Pipes;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using System.IO;

    namespace WindowsService
    {
        class PipeClient
        {
            public void Send(string SendStr, string PipeName, int TimeOut = 5000)
            {
                try
                {
                    NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous);


                    // The connect function will indefinitely wait for the pipe to become available
                    // If that is not acceptable specify a maximum waiting time (in ms)


                    pipeStream.Connect(TimeOut);

                    Debug.WriteLine("[Client] Pipe connection established");

                    byte[] _buffer = Encoding.UTF8.GetBytes(SendStr);
                    pipeStream.BeginWrite
                    (_buffer, 0, _buffer.Length, new AsyncCallback(AsyncSend), pipeStream);               


                }
                catch (TimeoutException oEX)
                {
                    Debug.WriteLine(oEX.Message);
                }
            }

            private void AsyncSend(IAsyncResult iar)
            {
                try
                {
                    // Get the pipe
                    NamedPipeClientStream pipeStream = (NamedPipeClientStream)iar.AsyncState;                

                    // End the write
                    pipeStream.EndWrite(iar);
                    pipeStream.Flush();
                    pipeStream.Close();
                    pipeStream.Dispose();
                }
                catch (Exception oEX)
                {
                    Debug.WriteLine(oEX.Message);
                }
            }
        }
    }

    And on OnStart Method()   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading.Tasks;

    using System.ServiceModel;
    using System.Drawing;



    namespace WindowsService
    {
        public partial class Service1 : ServiceBase
        {
            private PipeClient _pipeClient;
            private int _ctr;



            public Service1()
            {
                InitializeComponent();
                _ctr = 1;
            }

            EventLog log = new EventLog();

            protected override void OnStart(string[] args)
            {
                log.Source = "Hello";
                log.WriteEntry("Test", EventLogEntryType.Information);

                try {
                    _pipeClient = new PipeClient();
                    _pipeClient.Send(_ctr.ToString(), "TestPipe", 1000);
                    _ctr++;
                    _pipeClient = null;



                }
                catch(Exception ex)
                {
                    log.WriteEntry(ex.Message, EventLogEntryType.Information);
                }
                log.WriteEntry("Test 2", EventLogEntryType.Information);
                Timer1_Tick();
                log.WriteEntry("Test 3", EventLogEntryType.Information);
            }

            private void Timer1_Tick()
            {
                try
                {
                    _pipeClient = new PipeClient();
                    _pipeClient.Send(_ctr.ToString(), "TestPipe", 1000);
                    _ctr++;
                    _pipeClient = null;

                }
                catch (Exception ex)
                {
                    log.WriteEntry(ex.Message, EventLogEntryType.Information);
                }
            }

            protected override void OnStop()
            {
                _pipeClient = null;
            }
        }
    } Once you install this windows service and run it form GUI... then for the first time it will show respective message for next time it raising Access path denied error.

    please resolve it!

                                
    Thursday, February 25, 2016 2:48 PM

Answers