diff --git a/WpkgInstaller/IWpkgMessageCallbackHandlerContract.cs b/WpkgInstaller/IWpkgMessageCallbackHandlerContract.cs
deleted file mode 100755
index d277d59121523dbed3ae7a04ebe0b3813cf89870..0000000000000000000000000000000000000000
--- a/WpkgInstaller/IWpkgMessageCallbackHandlerContract.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.ServiceModel;
-
-namespace WpkgInstaller
-{
-    public interface IWpkgMessageCallbackHandlerContract
-    {
-        [OperationContract(IsOneWay = true)]
-        void HandleResponse(WpkgMessageResponse response);
-
-        [OperationContract(IsOneWay = true)]
-        void HandleMessage(WpkgMessageState status);
-    }
-}
diff --git a/WpkgInstaller/IWpkgMessageRequestHandlerContract.cs b/WpkgInstaller/IWpkgMessageRequestHandlerContract.cs
deleted file mode 100644
index e6bc7746cc6e0c0df3839f1ef8de67cd2adb2e23..0000000000000000000000000000000000000000
--- a/WpkgInstaller/IWpkgMessageRequestHandlerContract.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.ServiceModel;
-
-namespace WpkgInstaller
-{
-    public delegate WpkgMessageRequestType WpkgEventCallbackHandler(object sender, WpkgMessageRequest e);
-
-    [ServiceContract(Namespace = "https://www.ch.cam.ac.uk/WpkgNotifier",
-                     SessionMode = SessionMode.Required,
-                     CallbackContract = typeof(IWpkgMessageCallbackHandlerContract))]
-    public interface IWpkgMessageRequestHandlerContract
-    {
-        [OperationContract(IsOneWay = true)]
-        void HandleMessage(WpkgMessageRequestType type);
-    }
-}
diff --git a/WpkgInstaller/IWpkgNotifierMessageClient.cs b/WpkgInstaller/IWpkgNotifierMessageClient.cs
new file mode 100755
index 0000000000000000000000000000000000000000..3e8bcb93c081fa692a941c1cc501cd3db48e8499
--- /dev/null
+++ b/WpkgInstaller/IWpkgNotifierMessageClient.cs
@@ -0,0 +1,13 @@
+using System.ServiceModel;
+
+namespace WpkgInstaller
+{
+    public interface IWpkgNotifierMessageClient
+    {
+        [OperationContract(IsOneWay = true)]
+        void StatusLine(string msg);
+
+        [OperationContract(IsOneWay = true)]
+        void SetStatus(WpkgMessageState status);
+    }
+}
\ No newline at end of file
diff --git a/WpkgInstaller/IWpkgNotifierMessageServer.cs b/WpkgInstaller/IWpkgNotifierMessageServer.cs
new file mode 100755
index 0000000000000000000000000000000000000000..b1ec47cfc04c266898e212f3b3ff2377ab7c55cd
--- /dev/null
+++ b/WpkgInstaller/IWpkgNotifierMessageServer.cs
@@ -0,0 +1,18 @@
+using System.ServiceModel;
+
+namespace WpkgInstaller
+{
+
+    [ServiceContract(CallbackContract = typeof(IWpkgNotifierMessageClient))]
+    public interface IWpkgNotifierMessageServer
+    {
+        [OperationContract(IsOneWay = true)]
+        void Register(int pid);
+
+        [OperationContract(IsOneWay = true)]
+        void Unregister(int pid);
+
+        [OperationContract(IsOneWay = true)]
+        void ProcessRequest(WpkgMessageRequestType type);
+    }
+}
diff --git a/WpkgInstaller/WpkgInstaller.cs b/WpkgInstaller/WpkgInstaller.cs
index d522ba96455679e497ffbe9b3cf4e6f23613d7df..31f161b74d6b05f9c4717a75bfb514c0c6226d71 100644
--- a/WpkgInstaller/WpkgInstaller.cs
+++ b/WpkgInstaller/WpkgInstaller.cs
@@ -3,6 +3,8 @@ using System.ServiceProcess;
 using System.Diagnostics;
 using System;
 using System.ServiceModel;
+using System.Collections;
+using System.Collections.Generic;
 
 namespace WpkgInstaller
 {
@@ -28,18 +30,21 @@ namespace WpkgInstaller
         public int dwCheckPoint;
         public int dwWaitHint;
     };
-    public partial class WpkgInstaller : ServiceBase
+
+    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
+    public partial class WpkgInstaller : ServiceBase, IWpkgNotifierMessageServer
     {
 
         [DllImport("advapi32.dll", SetLastError = true)]
         private static extern bool SetServiceStatus(System.IntPtr handle, ref ServiceStatus serviceStatus);
+        private Dictionary<int, IWpkgNotifierMessageClient> clients;
 
-        private IWpkgMessageCallbackHandlerContract notifierCallbackHandler;
         public WpkgInstaller()
         {
             InitializeComponent();
             
             eventLog = new EventLog();
+            clients = new Dictionary<int, IWpkgNotifierMessageClient>();
             string eventSourceName = "WpkgInstaller Service";
             string logName = "WpkgNotifier";
 
@@ -88,14 +93,12 @@ namespace WpkgInstaller
 
         private void RunWpkgSync()
         {
-            notifierCallbackHandler.HandleMessage(WpkgMessageState.SYNCING);
             eventLog.WriteEntry("Starting sync", EventLogEntryType.Information);
             RunWpkgCommand("/synchronize");
         }
 
         private void RunWpkgQuery()
         {
-            notifierCallbackHandler.HandleMessage(WpkgMessageState.QUERYING);
             eventLog.WriteEntry("Starting query", EventLogEntryType.Information);
             RunWpkgCommand("/query:m");
         }
@@ -127,15 +130,13 @@ namespace WpkgInstaller
             process.BeginOutputReadLine();
             process.WaitForExit();
 
-            notifierCallbackHandler.HandleMessage(WpkgMessageState.IDLE);
-
             if(process.ExitCode == 0)
             {
-                notifierCallbackHandler.HandleMessage(WpkgMessageState.SUCCESS);
+                SetClientsState(WpkgMessageState.SUCCESS);
             }
             else
             {
-                notifierCallbackHandler.HandleMessage(WpkgMessageState.ERROR);
+                SetClientsState(WpkgMessageState.ERROR);
             }
             String msg = String.Format("wpkg command finished, with exit code {0}", process.ExitCode);
             eventLog.WriteEntry(msg, EventLogEntryType.Information);
@@ -146,8 +147,7 @@ namespace WpkgInstaller
         {
             if (e != null && e.Data != null)
             {
-                notifierCallbackHandler.HandleResponse(new WpkgMessageResponse(e.Data));
-                //eventLog.WriteEntry(e.Data, EventLogEntryType.Information);
+                // sent e.Data back to clients
             }
 
         }
@@ -170,44 +170,83 @@ namespace WpkgInstaller
         {
             try
             {
-                Uri BaseAddress = new Uri("net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier");
+                Uri uri = new Uri("net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier");
                 NetNamedPipeBinding binding = new NetNamedPipeBinding();
+                ServiceHost serviceHost = new ServiceHost(this, uri);
+                serviceHost.AddServiceEndpoint(typeof(IWpkgNotifierMessageServer), binding, "");
+
+                serviceHost.Open();
 
-                WpkgInstallerMessageService svc = new WpkgInstallerMessageService();
-                ServiceHost SvcHost = new ServiceHost(svc, BaseAddress);
-                SvcHost.AddServiceEndpoint(typeof(IWpkgMessageRequestHandlerContract), binding, "");
-                SvcHost.Open();
+                eventLog.WriteEntry("serviceHost now open");
 
-                (SvcHost.SingletonInstance as WpkgInstallerMessageService).WpkgEventCallback += new WpkgEventCallbackHandler(ProcessMessage);
             } 
             catch (Exception e)
             {
-                eventLog.WriteEntry(e.Message);
+                eventLog.WriteEntry(e.Message, EventLogEntryType.Error);
+                throw e;
             }
 
         }
 
-        private WpkgMessageRequestType ProcessMessage(object sender, WpkgMessageRequest e)
+        public void Register(int pid)
         {
-            if (notifierCallbackHandler == null)
+            eventLog.WriteEntry(String.Format("Register requested for {0}", pid));
+            IWpkgNotifierMessageClient client = OperationContext.Current.GetCallbackChannel <IWpkgNotifierMessageClient>();
+            clients.Add(pid, client);
+            
+            foreach(KeyValuePair<int, IWpkgNotifierMessageClient> kv in clients)
             {
-                notifierCallbackHandler = OperationContext.Current.GetCallbackChannel<IWpkgMessageCallbackHandlerContract>();
+                try
+                {
+                    kv.Value.StatusLine(String.Format("Register requested for {0}", pid));
+                }
+                catch (Exception e)
+                {
+                    eventLog.WriteEntry("Error communicating with client " + kv.Key + " " + e.ToString(), EventLogEntryType.Warning);
+                }
             }
+        }
 
-            eventLog.WriteEntry(string.Format("Got {0}", e.Type));
-            switch(e.Type)
+        public void Unregister(int pid)
+        {
+            if(clients.Remove(pid))
+            {
+                eventLog.WriteEntry(String.Format("Client {0} unregistered", pid));
+            }
+            else
+            {
+                eventLog.WriteEntry(String.Format("Unknown client {0} requested to unregister", pid), EventLogEntryType.Warning);
+            }
+        }
+        public void ProcessRequest(WpkgMessageRequestType type)
+        {
+            switch (type)
             {
                 case WpkgMessageRequestType.DO_SYNC:
+                    SetClientsState(WpkgMessageState.SYNCING);
                     RunWpkgSync();
                     break;
                 case WpkgMessageRequestType.RUN_QUERY:
+                    SetClientsState(WpkgMessageState.QUERYING);
                     RunWpkgQuery();
                     break;
 
             }
-            return WpkgMessageRequestType.DONE;
-
+        }
 
+        private void SetClientsState(WpkgMessageState state)
+        {
+            foreach (KeyValuePair<int, IWpkgNotifierMessageClient> kv in clients)
+            {
+                try
+                {
+                    kv.Value.SetStatus(state);
+                }
+                catch (Exception e)
+                {
+                    eventLog.WriteEntry("Error communicating with client " + kv.Key + " " + e.ToString(), EventLogEntryType.Warning);
+                }
+            }
         }
     }
 }
diff --git a/WpkgInstaller/WpkgInstaller.csproj b/WpkgInstaller/WpkgInstaller.csproj
index 31ed41a0e3f6238f978ad69503ef0e735dcec473..2c6b5697deb58b9f1444d34a4444db8236b2f40b 100644
--- a/WpkgInstaller/WpkgInstaller.csproj
+++ b/WpkgInstaller/WpkgInstaller.csproj
@@ -70,7 +70,8 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="IWpkgMessageCallbackHandlerContract.cs" />
+    <Compile Include="IWpkgNotifierMessageClient.cs" />
+    <Compile Include="IWpkgNotifierMessageServer.cs" />
     <Compile Include="ProjectInstaller.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -85,8 +86,6 @@
     </Compile>
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="WpkgInstallerMessageService.cs" />
-    <Compile Include="IWpkgMessageRequestHandlerContract.cs" />
     <Compile Include="WpkgMessageRequest.cs" />
     <Compile Include="WpkgMessageResponse.cs" />
     <Compile Include="WpkgMessageState.cs" />
diff --git a/WpkgInstaller/WpkgInstallerMessageService.cs b/WpkgInstaller/WpkgInstallerMessageService.cs
deleted file mode 100644
index bf72e2d8df5a16bcfba167db12d14e69f9435d0e..0000000000000000000000000000000000000000
--- a/WpkgInstaller/WpkgInstallerMessageService.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.ServiceModel;
-
-namespace WpkgInstaller
-{
-    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
-    class WpkgInstallerMessageService : IWpkgMessageRequestHandlerContract
-    {
-        public event WpkgEventCallbackHandler WpkgEventCallback = delegate { return WpkgMessageRequestType.DONE; };
-
-        public void HandleMessage(WpkgMessageRequestType type)
-        {
-            WpkgEventCallback(this, new WpkgMessageRequest(type));
-        }
-    }
-}
diff --git a/WpkgNotifier/TrayNotifier.cs b/WpkgNotifier/TrayNotifier.cs
index a6b9a0916f61f43c8b88227fac7d598c123ce939..64855fa4b0ba8b5ef569e78bcd3b8122b694e32f 100644
--- a/WpkgNotifier/TrayNotifier.cs
+++ b/WpkgNotifier/TrayNotifier.cs
@@ -8,16 +8,20 @@ using WpkgInstaller;
 
 namespace WpkgNotifier
 {
-    class TrayNotifier : ApplicationContext, IWpkgMessageCallbackHandlerContract
+    class TrayNotifier : ApplicationContext, IWpkgNotifierMessageClient
     {
         private NotifyIcon notifyIcon;
-        private IWpkgMessageRequestHandlerContract messageChannel;
+        
         private EventLog eventLog;
         private WpkgMessageState state;
+        private IWpkgNotifierMessageServer server;
+        private int pid;
 
         public TrayNotifier()
         {
-
+            Process currentProcess = Process.GetCurrentProcess();
+            pid = currentProcess.Id;
+    
             eventLog = new EventLog();
             string eventSourceName = "TrayNotifier";
             string logName = "WpkgNotifier";
@@ -33,6 +37,8 @@ namespace WpkgNotifier
             
             OpenMessageChannel();
 
+            Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
+
             MenuItem actionsMenu = new MenuItem("Actions");
             MenuItem syncMenuItem = new MenuItem("Sync", new EventHandler(RequestSync));
             MenuItem queryMenuItem = new MenuItem("Query", new EventHandler(RequestQuery));
@@ -64,24 +70,30 @@ namespace WpkgNotifier
             };
         }
 
+        private void OnApplicationExit(object sender, EventArgs e)
+        {
+            server.Unregister(pid);
+        }
+
         private void OpenMessageChannel()
         {
             eventLog.WriteEntry("Trying to open channel");
             try
             {
-                string address = "net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier";
-
                 NetNamedPipeBinding binding = new NetNamedPipeBinding();
+                string uri = "net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier";
                 InstanceContext context = new InstanceContext(this);
-                DuplexChannelFactory<IWpkgMessageRequestHandlerContract> factory = new DuplexChannelFactory<IWpkgMessageRequestHandlerContract>(context, binding, address);
+                DuplexChannelFactory<IWpkgNotifierMessageServer> channelFactory = 
+                    new DuplexChannelFactory<IWpkgNotifierMessageServer>(context, binding, uri);
 
-                messageChannel = factory.CreateChannel();
+                server = channelFactory.CreateChannel();
                 eventLog.WriteEntry("channel created");
+                server.Register(pid);
+                eventLog.WriteEntry("Registered with server");
             }
             catch (Exception e)
             {
                 eventLog.WriteEntry("problem creating channel");
-
                 eventLog.WriteEntry(e.Message);
             }
         }
@@ -89,13 +101,13 @@ namespace WpkgNotifier
         void RequestSync(object sender, EventArgs e)
         {
             notifyIcon.ContextMenu.MenuItems[0].Enabled = false;
-            messageChannel.HandleMessage(WpkgMessageRequestType.DO_SYNC);
+            server.ProcessRequest(WpkgMessageRequestType.DO_SYNC);
         }
 
         void RequestQuery(object sender, EventArgs e)
         {
             notifyIcon.ContextMenu.MenuItems[0].Enabled = false;
-            messageChannel.HandleMessage(WpkgMessageRequestType.RUN_QUERY);
+            server.ProcessRequest(WpkgMessageRequestType.RUN_QUERY);
         }
 
         void ManageSoftware(object sender, EventArgs e)
@@ -111,6 +123,8 @@ namespace WpkgNotifier
             Application.Exit();
         }
 
+
+
         public void SetToolTip(string msg)
         {
             notifyIcon.Text = msg;
@@ -121,7 +135,7 @@ namespace WpkgNotifier
             eventLog.WriteEntry(response.Message);
         }
 
-        public void HandleMessage(WpkgMessageState status)
+        public void SetStatus(WpkgMessageState status)
         {
             this.state = status;
             switch (status)
@@ -145,5 +159,10 @@ namespace WpkgNotifier
                     break;
             }
         }
+
+        public void StatusLine(string msg)
+        {
+            SetToolTip(msg);
+        }
     }
 }