Click here to Skip to main content
15,887,328 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a window forms that is starting a window service I just need to send information whatever going inside that window service. So, I basically sending messages form window service to window form.

What I have tried:

#Window FORMS::

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
NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

// 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[255];

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

// 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 form just checking it:

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

IN Constructor of that form:
_pipeServer = new PipeServer();
_pipeServer.PipeMessage += new DelegateMessage(PipesMessageHandler);

And on From_Load::
try
{
_pipeServer.Listen("ProcessLogs");
txtLogs.Text = "...";
}
catch (Exception ex)
{
txtLogs.Text = "Error Listening"+ ex.Message+" >> "+ ex.InnerException;
}


---------------- In Window Service ::: ----------

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 = 1000)
{
try
{
//NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous, TokenImpersonationLevel.None, HandleInheritability.None);
//NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous, TokenImpersonationLevel.None, System.IO.HandleInheritability.Inheritable);
NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.WriteThrough, TokenImpersonationLevel.Anonymous, System.IO.HandleInheritability.Inheritable);

PipeSecurity pipeSa = new PipeSecurity();
pipeSa.SetAccessRule(new PipeAccessRule("Everyone",
PipeAccessRights.ReadWrite, AccessControlType.Allow));
pipeStream.SetAccessControl(pipeSa);

// 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, 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::

_pipeClient = new PipeClient();
_pipeClient.Send("Testing Pipe Message", "ProcessLogs", 1000);


Please help me out.

Thanks!
Posted
Updated 1-Mar-16 0:30am

1 solution

It might have permission issue: So, need to provide required access rights.

C#
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);


And to overcome the problem of listening only once follow this setp:
-> Right click on respective service > Properties > Log On > Log on as: Local System Account and tick Allow service to interact with desktop.
Or Go to ServiceProcessInstaller property and Set account as LocalSystem.

Cheers!!!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900