Simple Inter-Process Communication In VB.Net
Posted by anoriginalidea on August 9, 2007
There are plenty of articles around for inter process communication, using remoting, custom windows messages and named pipes. In my .net career I think I’ve used all of them. In this article I’ll outline a technique I’ll be using that I think is quite simple.
In .net Framework 2.0, Microsoft introduced the new System.Runtime.Remoting.Channels.Ipc remoting channel , which provides one of the easiest (prior to using WCF) techniques.
In this example we have a single server process which is communicated to via client processes.
SharedInterfaces
Firstly, as with all remoting it is necessary to share a type that defines the api you desire between client and server processes. One of the easiest things to do is to create an interface.
For the sake of this example, I created an assembly called “Shared Interfaces” containing an interface called “ICommunicationService”:
Public Interface ICommunicationService
Sub SaySomething(ByVal text As String)
End Interface
Server
For the Server in this example, I created a console application (it can be any sort of process).
The Server project contains two classes:
- An implementation of ICommunicationService called “CommunicationService”
- A Main that registers to CommunicationService class for acess
The CommunicationService class implements the interface and inherits from MarshalByRefObject :
Public Class CommunicationService Public Sub SaySomething(ByVal text As String) Implements SharedInterfaces.ICommunicationService.SaySomething
The main registers the type:
Inherits MarshalByRefObject
Implements SharedInterfaces.ICommunicationService
Console.WriteLine("The client said : " & text)
End Sub
End Class
Imports System.Runtime.Remoting ChannelServices.RegisterChannel(ipcCh, False) Console.WriteLine("Press ENTER to quit")
Client
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Ipc
Module Main
Sub Main()
Dim ipcCh As IpcChannel
ipcCh = New IpcChannel("IPChannelName")
RemotingConfiguration.RegisterWellKnownServiceType( _
GetType(CommunicationService), "SreeniRemoteObj", _
WellKnownObjectMode.Singleton)
Console.ReadLine()
End Sub
End Module
The client project is written as a Winform with a textbox and a button. The button click contains this code:
Imports System.Runtime.Remoting Private Sub cmdSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSend.Click Dim obj As SharedInterfaces.ICommunicationService = _ ChannelServices.UnregisterChannel(ipcCh) End Class
The code basically gets a reference to the remote object and invokes the “SaySomething” message, passing through a value.
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Ipc
Public Class Form1
Dim ipcCh As New IpcChannel("myClient")
ChannelServices.RegisterChannel(ipcCh, False)
DirectCast(Activator.GetObject(GetType(SharedInterfaces.ICommunicationService), _
"ipc://IPChannelName/SreeniRemoteObj"), SharedInterfaces.ICommunicationService)
obj.SaySomething(txtText.Text)
End Sub
As you can see, it doesn’t take much code to communicate between processes.
Improvements
Further improvements to the code will involve ensuring security (making sure that only desirable client processes are calling).
Links
- This article was based on “.NET Remoting Using a New IPC Channel”
- You may also like to take a look at “.NET Remoting with an easy example”


Damjan said
Good tutorial. Tnx.
Hubert Licman said
Very usable example. You too much help me. Thanks.
Mark Nunn said
This article looks great but unfortunately I can’t seem to get it to work with .NET framework v3.5 and Visual Basic 2008.
It fails on the line ‘Imports System.Runtime.Remoting.Channels.Ipc’ as it cannot find ‘Ipc’. I wonder what I am doing wrong!
anoriginalidea said
Mark,
Simply add a reference to “System.Runtime.Remoting” and ipc remoting bliss will be yours.
Have fun!
David Leland said
Great article and sample code. I have a requirement to create an “Instant Messenger” application and as such need the “Server” and “Client” pieces to reside within a single program. Can’t seem to find the magic combination – any suggestions would be greatly appreciated.
Dave
Steve Schoonover said
This example worked fine for my purposes. I did use the console app for the Server portion like this example shows.
What I would like to do is use a Windows Form instead of a console app to display my values passed through the SaySomething method. When I attempt to create a Form and startup my application as a Windows Application (not a console app) I am unable to reference and modify the label on the Server form. I’ve determined the CommunicationService Class is a separate thread from the one launched through the Server form I’ve created.
Is there a way to have this SaySomething method in the Server app reference the new Windows form I’ve created?
Thanks for any help.
Steve
anoriginalidea said
Hi Steve,
There are a few ways to communicate between threads in this scenario.
One way is to put a reference to your display form in a “Shared” variable, then use the “BeginInvoke” method on the form to update the text property.
Another way is to store the “say” text in a collection, exposed as a shared variable, then use a timer on the Winform to periodically bind (read the data from) the collection if the data changes.
Regards
Julian
wos said
Hey Dude!
Great job, thank you very much!
There is just one thing I can’t deal with – if you wanna combine server and client in one program, the code in the “SaySomething” method is done twice, ain’t it?
Thanks for the help,
wos
wos said
Hey there!
It’s me again – found a solution.
Problem was that I was using windowsform – object in the “SaySomething” method.
Sure it’s just fired by the server side, but as there are two instances of the program with the windowsform – object being public, my application did it once for the form in Instance I and then for form in instance II.
If anyone needs the solution code, just mail.
Nice evening to ya all.
Keith Thompson said
Hi,
Sorry if this is a naive question… I’m just getting into this… I got everything working ok, but I need multiple clients to be able to send messages to the server, but if I try sending a message from a client, whilst the server is dealing with another, I get an exception. I’ve tried setting “WellKnownObjectMode.SingleCall”, to allow an instance per client (I think!), but I still get the same error. Do I need to / can I set up a range of ports to use? Do I need to set up the client to wait until the port is free? Any help would be very gratefully accepted
Bobbie said
I ran into alot of grief getting this to work on XP. Turned out what worked was
Dim properties As IDictionary = New Hashtable() properties.Add("authorizedGroup", "Users") properties.Add("portName", "myClient") properties.Add("rejectRemoteRequests", True) Dim ipcCh As IpcChannel ipcCh = New IpcChannel(properties, Nothing, Nothing)instead of
ipcCh = New IpcChannel("IPChannelName")I hope this saves someone else the 2 hours of grief I had trying to get it to work.
Oh, and I also had to use
ChannelServices.GetChannel("myClient")instead of
Dim ipcCh As New IpcChannel("myClient") ChannelServices.RegisterChannel(ipcCh, False)on the receiving end.
Mitch said
This is a great article, but I’m having some difficulties. I’ve followed your directions and got two applications communicating well. However, in the “SaySomething” sub, instead of a simple console.writeline command, I decided to call another subroutine that is in the code for one of my forms. This subroutine is attempting to change the form in some way — add text to a label, change the opacity of the form, whatever — however, I can’t seem to manipulate the form at all. Does anyone know why? PLEASE HELP.
anoriginalidea said
Hi Mitch,
Applications written as Winforms or WPF have to have their UI elements (such as labels and textboxes) updated on the “UI Thread”.
Because “Say Something” is invoked by a non-ui thread, you have to to “marshall” the update onto the ui thread.
There are two ways to do this (as I noted in a previous comment):
One way is to put a reference to your display form in a “Shared” variable, then use the “BeginInvoke” method on the form to update the text property.
Another way is to store the “say” text in a collection, exposed as a shared variable, then use a timer on the Winform to periodically bind (read the data from) the collection if the data changes.
Hope this helps
Regards
Julian