Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7885501
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T05:05:16+00:00 2026-06-03T05:05:16+00:00

I am using Named Pipes to communicate with a process. I have been able

  • 0

I am using Named Pipes to communicate with a process. I have been able to make it work with the following code. (Original code found here : via archive.org )

class ProgramPipeTest
    {

        public void ThreadSenderStartClient(object obj)
        {
            // Ensure that we only start the client after the server has created the pipe
            ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".","ToSrvPipe",PipeDirection.Out,PipeOptions.None))
            {
                // The connect function will indefinately wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                pipeStream.Connect();

                Console.WriteLine("[Client] Pipe connection established");
                using (StreamWriter sw = new StreamWriter(pipeStream))
                {
                    sw.AutoFlush = true;
                    string temp;
                    Console.WriteLine("Please type a message and press [Enter], or type 'quit' to exit the program");
                    while ((temp = Console.ReadLine()) != null)
                    {
                        if (temp == "quit") break;
                        sw.WriteLine(temp);
                    }
                }
            }
        }

        public void ThreadStartReceiverClient(object obj)
        {
            // Ensure that we only start the client after the server has created the pipe
            ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "FromSrvPipe", PipeDirection.In, PipeOptions.None))
            {
                // The connect function will indefinately wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                pipeStream.Connect();

                Console.WriteLine("[ClientReceiver] Pipe connection established");

                using (StreamReader sr = new StreamReader(pipeStream))
                {
                    // Display the read text to the console
                    string temp;
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine("Received from server: {0}", temp);
                    }
                }
            }
        }

        static void Main(string[] args)
        {

            // To simplify debugging we are going to create just one process, and have two tasks
            // talk to each other. (Which is a bit like me sending an e-mail to my co-workers)

            ProgramPipeTest Client = new ProgramPipeTest();

            Thread ClientThread = new Thread(Client.ThreadSenderStartClient);
            Thread ReceivedThread = new Thread(Client.ThreadStartReceiverClient);

            ClientThread.Start();
            ReceivedThread.Start();


        }
    }

Everything works as intended. I am able to issue commands to my target process (audacity).

My issue is, I basically want to wrap a C# GUI around this code, but am not sure how to modify it so that the communication is done without having to use the console, as commands would be issued via the GUI or from the code.

I have tried turning the streamWriter sw into a class variable, exposing it via property and calling sw.WriteLine() with a method, but that doesn’t seem to work.

So I am unsure how to encapsulate the stream back and forth nicely within an object.

I found this article which seemed like it was spot on, Using Named Pipes to Connect a GUI to a Console App in Windows, but unfortunately it does not seem to come with any code and is kind of over my head without any to refer to.

So how can I use named pipes without having to use the console to issue the commands ?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T05:05:17+00:00Added an answer on June 3, 2026 at 5:05 am

    What you want to do is take the main pieces of logic which are the sender, the receiver out of that code and rewrite it into a re-usable class that can be used like a purpose-specific wrapper class.

    Perhaps the code below could serve as a guideline (I have NOT checked to see if this works, it might require minor changes)

    public sealed class ResponseReceivedEventArgs : EventArgs
    {
        public ResponseReceivedEventArgs(string id, string response)
        {
            Id = id;
            Response = response;
        }
    
        public string Id
        {
            private set;
            get;
        }
    
        public string Response
        {
            private set;
            get;
        }
    }
    
    public delegate void ResponseReceived(object sender, ResponseReceivedEventArgs e);
    
    public sealed class NamedPipeCommands
    {
        private readonly Queue<Tuple<string, string>> _queuedCommands = new Queue<Tuple<string,string>>();
        private string _currentId;
    
        private readonly Thread _sender;
        private readonly Thread _receiver;
    
        // Equivalent to receiving a "quit" on the console
        private bool _cancelRequested; 
    
        // To wait till a response is received for a request and THEN proceed
        private readonly AutoResetEvent _waitForResponse = new AutoResetEvent(false);
    
        // Lock to modify the command queue safely
        private readonly object _commandQueueLock = new object();
    
        // Raise an event when a response is received
        private void RaiseResponseReceived(string id, string message)
        {
            if (ResponseReceived != null)
                ResponseReceived(this, new ResponseReceivedEventArgs(id, message));
        }
    
        // Add a command to queue of outgoing commands
        // Returns the id of the enqueued command
        // So the user can relate it with the corresponding response
        public string EnqueueCommand(string command)
        {
            var resultId = Guid.NewGuid().ToString();
            lock (_commandQueueLock)
            {
                _queuedCommands.Enqueue(Tuple.Create(resultId, command));
            }
            return resultId;
        }
    
        // Constructor. Please pass in whatever parameters the two pipes need
        // The list below may be incomplete
        public NamedPipeCommands(string servername, string pipeName)
        {
            _sender = new Thread(syncClientServer =>
            {
                // Body of thread
                var waitForResponse = (AutoResetEvent)syncClientServer;
    
                using (var pipeStream = new NamedPipeClientStream(servername, pipeName, PipeDirection.Out, PipeOptions.None))
                {
                    pipeStream.Connect();
    
                    using (var sw = new StreamWriter(pipeStream) { AutoFlush = true })
                        // Do this till Cancel() is called
                        while (!_cancelRequested)
                        {
                            // No commands? Keep waiting
                            // This is a tight loop, perhaps a Thread.Yield or something?
                            if (_queuedCommands.Count == 0)
                                continue;
    
                            Tuple<string, string> _currentCommand = null;
    
                            // We're going to modify the command queue, lock it
                            lock (_commandQueueLock)
                                // Check to see if someone else stole our command
                                // before we got here
                                if (_queuedCommands.Count > 0)
                                    _currentCommand = _queuedCommands.Dequeue();
    
                            // Was a command dequeued above?
                            if (_currentCommand != null)
                            {
                                _currentId = _currentCommand.Item1;
                                sw.WriteLine(_currentCommand.Item2);
    
                                // Wait for the response to this command
                                waitForResponse.WaitOne();
                            }
                        }
                }
            });
    
            _receiver = new Thread(syncClientServer =>
            {
                var waitForResponse = (AutoResetEvent)syncClientServer;
    
                using (var pipeStream = new NamedPipeClientStream(servername, pipeName, PipeDirection.In, PipeOptions.None))
                {
                    pipeStream.Connect();
    
                    using (var sr = new StreamReader(pipeStream))
                        // Do this till Cancel() is called
                        // Again, this is a tight loop, perhaps a Thread.Yield or something?
                        while (!_cancelRequested)
                            // If there's anything in the stream
                            if (!sr.EndOfStream)
                            {
                                // Read it
                                var response = sr.ReadLine();
                                // Raise the event for processing
                                // Note that this event is being raised from the
                                // receiver thread and you can't access UI here
                                // You will need to Control.BeginInvoke or some such
                                RaiseResponseReceived(_currentId, response);
    
                                // Proceed with sending subsequent commands
                                waitForResponse.Set();
                            }
                }
            });
        }
    
        public void Start()
        {
            _sender.Start(_waitForResponse);
            _receiver.Start(_waitForResponse);
        }
    
        public void Cancel()
        {
            _cancelRequested = true;
        }
    
        public event ResponseReceived ResponseReceived;
    }
    

    You can see that I have created abstractions for the Console.ReadLine (the command queue) and Console.WriteLine (the event). The “quit” is also a boolean variable that is set by the “Cancel()” method now. Obviously this isn’t the most optimal/correct way of doing it – I am just showing you one way to relate the imperative code from above into a wrapper class that can be re-used.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Lately I've been favoring using named pipes (option --enable-named-pipes) in MySQL running on windows,
I'm using the following code to write data through a named pipe from one
I have 2 applications communicating using named pipes. Main program calls client program and
Hi i have a couple of question about using named pipes. Firstly, when trying
I remember using Named Pipes for communicating between 2 machines (back in Windows NT).
I'm using named pipes as the log file for the access_log of my nginx,
Obviously the point of using named constants over magic numbers is for code clarity
just a general question are there any issues with using named pipes from a
I was studying the MSDN examples of using named pipes: Named pipe server using
I'm using a named pipe to communicate between a PHP script and a C++

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.