Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Create a C# Listener Service for MSMQ as a Windows Service

I'll start by saying I'm not a .NET developer, but have been thrown into a project where I need to use MSMQ so a classic ASP web application can send messages to a C# Windows Service that handles the processing. I have experience integrating other message queues with other languages, but like I mentioned, I don't have much experience with .NET and Windows development so some guidance would be much appreciated.

Here are my questions...

  1. Could someone provide some basic C# code that listens to an existing MSMQ queue and responds to the new message by doing something simple like writing the current timestamp to a log file or sending an email?

  2. How do I package this code up in Visual Studio .NET to create and install a Windows Service? (What type of project should it be, etc. I'm using Visual C# 2010 Express.)

  3. Finally, I'm not sure which version and/or implementation of MSMQ I need to be using for my requirements with classic ASP. I think the COM version is what I need, but I've also read about a new WCF version, as well as differences between 3.0 and 4.0. Could someone please give me direction on which version I should be using?

Many thanks!

like image 849
philfeyn Avatar asked Oct 18 '10 03:10

philfeyn


People also ask

How is C created?

The origin of C is closely tied to the development of the Unix operating system, originally implemented in assembly language on a PDP-7 by Dennis Ritchie and Ken Thompson, incorporating several ideas from colleagues. Eventually, they decided to port the operating system to a PDP-11.


2 Answers

You can wait for a message on a given queue using the following code (You want to use the private queue named SomeQueue on your computer, named ComputerName => QueueName = @"ComputerName\private$\SomeQueue")

    public void AsyncWatchQueue(object encapsulatedQueueName)
    {
        Message newMessage;
        MessageQueue queue;

        string queueName = encapsulatedQueueName as string;
        if (queueName == null)
            return;

        try
        {
            if (!MessageQueue.Exists(queueName))
                MessageQueue.Create(queueName);
            else
            {
                queue = new MessageQueue(queueName);

                if (queue.CanRead)
                    newMessage = queue.Receive();
            }
            HandleNewMessage(newMessage); // Do something with the message
        }
        // This exception is raised when the Abort method 
        // (in the thread's instance) is called
        catch (ThreadAbortException e) 
        {
            //Do thread shutdown
        }
        finally
        {
            queue.Dispose();
        }
    }

Note: the Receove method will block untill a message is received at which point it'll remove the message from the queue and return it.

edit: added code for the implementation of the multithreaded portion (and renamed the above method signature)

Thread Creation Code:

        public Thread AddWatchingThread(string QueueName)
    {
        Thread Watcher = 
            new Thread(new ParameterizedThreadStart(AsyncWatchQueue));
        Watcher.Start(QueueName);
        // The thread instance is used to manipulate (or shutdown the thread)
        return Watcher; 
    }

I'll just note, that this is untested cod, it's just an quick example

like image 131
Neowizard Avatar answered Sep 17 '22 20:09

Neowizard


As far as I know, Visual Studio Express does not have a project template for a service. That does not mean you cannot write a windows service with VSE, just that you will not have a template to get you started.

To create a service you can just create a normal Console application. Create the service class which will be responsible for the actual service implementation. It will look something like this

using System.ServiceProcess;

namespace WindowsService1
{
  public partial class Service1 : ServiceBase
  {
    public Service1()
    {
      InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
    }

    protected override void OnStop()
    {
    }
  }
}

Then the Service startup code can go into the Main function of your service.

using System.ServiceProcess;

namespace WindowsService1
{
  static class Program
  {
    static void Main()
    {
      ServiceBase[] ServicesToRun;
      ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };
      ServiceBase.Run(ServicesToRun);
    }
  }
}

That should give you the basic framework for your service. The other thing you will need is to add an installer for the service so that it can be installed as a service. The following should get you started, note I have note tested this.

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService1
{
  [RunInstaller(true)]
  public class ProjectInstaller : Installer
  {
    private ServiceProcessInstaller serviceProcessInstaller1;
    private ServiceInstaller serviceInstaller1;

    public ProjectInstaller()
    {
      this.serviceProcessInstaller1 = new ServiceProcessInstaller();
      this.serviceInstaller1 = new ServiceInstaller();

      this.serviceProcessInstaller1.Password = null;
      this.serviceProcessInstaller1.Username = null;

      this.serviceInstaller1.ServiceName = "Service1";

      this.Installers.AddRange(new System.Configuration.Install.Installer[] {
        this.serviceProcessInstaller1,
        this.serviceInstaller1});
    }
  }
}

Given the above, you should have enough to search around or ask for more details around the service creation. As for the MSMQ listener, you can use the following MSDN article as a starting point

http://msdn.microsoft.com/en-us/library/ms978425.aspx

like image 42
Chris Taylor Avatar answered Sep 21 '22 20:09

Chris Taylor