ASP.NET and IPC Remoting

I'm creating a .NET 2.0 ASP.NET web service as a front end to several Windows Services (also built using .NET 2.0) and want to use IPC since the web service and the Windows Services will be running on the same machine.

I don't want to use XML configuration files. I want to do it in code. It works with a console app to the Windows Service, but the ASP.NET web service blows chunks.

Failed to connect to an IPC port:  Access Denied

Search. Search. Search. One clue about "authorizedGroup" = "Everyone" but no code. Tinker. Stumble. Search. Tinker. Finally. Here's the final result in the Windows Service server:

Dictionary<string, string> props = new Dictionary<string, string>();
props.Add("authorizedGroup", "Everyone");
props.Add("portName", "ServerPortName");
serverChannel = new IpcServerChannel(props, null);
ChannelServices.RegisterChannel(serverChannel, true);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalByRefObjectSubClass),
   "ServerAppName", WellKnownObjectMode.SingleCall);
serverChannel.StartListening(null);

With the client setup like this in the web service:

using System;
using System.Data;
using System.Configuration;
using System.Threading;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using MyRemotingInterfaces;

public class RemotingClientFactory
{
   private static Mutex mut = new Mutex();
   private static WellKnownClientTypeEntry remoteEntry;
   private static IpcClientChannel remoteChannel;
   private static string remoteUrl = "ipc://RemoteExampleRemoteServer/RemoteExampleRemote";

   static RemotingClientFactory() { }

   public static IMyRemoteObject CreateRemote()
   {
      if (remoteChannel == null || remoteEntry == null)
      {
         mut.WaitOne();
         try
         {
            if (remoteChannel == null)
            {
               remoteChannel = new IpcClientChannel();
               ChannelServices.RegisterChannel(remoteChannel, true);
            }
            if (remoteEntry == null)
            {
               remoteEntry =
                 new WellKnownClientTypeEntry(typeof(MyRemotingInterfaces.IMyRemoteObject),
                       remoteUrl);
               RemotingConfiguration.RegisterWellKnownClientType(remoteEntry);
            }
         }
         finally
         {
            mut.ReleaseMutex();
         }
      }
      try
      {
         IMyRemoteObject obj =
          
(IRemoteExampleRemote)Activator.GetObject(remoteEntry.ObjectType, remoteUrl);
         return obj;
      }
      catch(Exception e)
      {
         //TODO log then rethrow
         throw e;
      }
   }
}

And it works like a charm. It's not perfect, I'm sure. But it's a start. And it didn't seem like anyone had or wanted to post their solution to the newsgroups or anywhere else I could find.

Let me know if you find a better way or if this helps you. And good luck.

Easy Debug Windows Service

I know this problem has been solved many times and written about many times, but every time I go to create a new Windows Service project, I end up re-researching how to debug and step through code in a Windows Service project in Visual Studio.

I've done it now, again, building my first real set of Windows Service projects in Visual Studio 2005 and this time I took the compiler directive approach. It's been done before, sure, and many have written about it, but for my own short term memory's sake, here's my solution.

Step One
Create the Windows Service project using the New Project wizard and the Windows Service template.

Step Two
Modify the nicely created program.cs file as follows:

using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
#if (DEBUG)
   class Program
#else
   static class Program
#endif
   {
      /// 
      /// The main entry point for the application.
      /// 
#if (DEBUG)
      static void Main(string[] args)
#else
      static void Main()
#endif
      {
#if (DEBUG)
         ServiceRunner sr = new ServiceRunner();
         sr.Start(args);
         Console.WriteLine("Started... Hit enter to stop...");
         Console.ReadLine();
         sr.Stop();
#else
         ServiceBase[] ServicesToRun;
         ServicesToRun = new ServiceBase[] { new Service1() };
         ServiceBase.Run(ServicesToRun);
#endif
      }
   }
}

Step Three
Modify the Service1.cs file as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
   public partial class Service1 : ServiceBase
   {
      private ServiceRunner serviceRunner = null;
      public Service1()
      {
         InitializeComponent();
         serviceRunner = new ServiceRunner();
      }

      protected override void OnStart(string[] args)
      {
         serviceRunner.Start(args);
      }

      protected override void OnStop()
      {
         serviceRunner.Stop();
      }
   }

   internal class ServiceRunner
   {
      public void Start(string[] args)
      {
         //TODO: Add code that will execute on start.
      }
      public void Stop()
      {
         //TODO: Add code that will execute on stop.
      }
   }
}

Step Four
Change the output type (in properties page of the project) to console application.

Now debug away!

OpenNLP for .NET

I recently ran into Richard Northedge's excellent article and C# rendition of the OpenNLP libraries as posted on Code Project. It's a fascinating toolset that presents common, ordinary coders like me with the opportunity to explore and build solutions previously the exclusive domain of guys with thick black plastic frames and lab coats.

I just wish I'd had this tool back in high school when the English teacher was having us waste our time diagramming sentences. But I doubt one could have stuffed this sort of code into a Commodore PET with 32K of RAM and a 4Khz 8 bit 6502 processor. Ah, those were the days. Life was simple. But not nearly so much fun as now.

I don't pretend to understand everything in the OpenNLP library, but I'm learning. Currently I'm exploring how this library might help me in search and content analysis for an ongoing project. As I learn more, I'll post more. For now, I'd love to hear from you if you've had any experience in building real-world applications using this library (even if it was the original java incantation).