The bare minimum needed to write a MSMQ sample application
Asked Answered
T

2

117

I have been researching for over an hour and finding great samples of how to use MSMQ in C# and even one full chapter of a book about Message Queue...But for a quick test all I need is to cover is this scenario, not even in a perfect way, just for a quick demo:

"Application A": Writes a Message to Message Queue. ( Application A is a C# windows service) Now I open "Application B" ( it is a C# winForms app ) and I check MSMQ and I see oh I have a new Message.

That's it... All I need for a simple demo.

Could anyone please help me with a code sample for this? Much appreciated.

Tinner answered 18/6, 2012 at 4:0 Comment(4)
what is down vote for? If you know something about the topic, Ok teach the rest of us.Tinner
@Sascha: read the beginning of my post: "I have been researching for over an hour and finding great samples of how to use MSMQ in C# and even one full chapter of a book about Message Queue...But for a quick test all I need is to cover is this scenario, not even in a perfect way, just for a quick demo"Tinner
Getting issue in MSMQ #29226101Sputter
Check this MSDN article as well msdn.microsoft.com/en-us/library/…Rianon
W
133
//From Windows Service, use this code
MessageQueue messageQueue = null;
if (MessageQueue.Exists(@".\Private$\SomeTestName"))
{
    messageQueue = new MessageQueue(@".\Private$\SomeTestName");
    messageQueue.Label = "Testing Queue";
}
else
{
    // Create the Queue
    MessageQueue.Create(@".\Private$\SomeTestName");
    messageQueue = new MessageQueue(@".\Private$\SomeTestName");
    messageQueue.Label = "Newly Created Queue";
}
messageQueue.Send("First ever Message is sent to MSMQ", "Title");

//From Windows application
MessageQueue messageQueue = new MessageQueue(@".\Private$\SomeTestName");
System.Messaging.Message[] messages = messageQueue.GetAllMessages();

foreach (System.Messaging.Message message in messages)
{
    //Do something with the message.
}
// after all processing, delete all the messages
messageQueue.Purge();

For more complex scenario, you could use Message objects to send the message, wrap your own class object inside it, and mark your class as serializable. Also be sure that MSMQ is installed on your system

Whopping answered 18/6, 2012 at 5:4 Comment(10)
Question: at the top that you are Creating the MessageQueue, we need both of these? MessageQueue.Create(@".\Private$\SomeTestName"); messageQueue = new MessageQueue(@".\Private$\SomeTestName");Tinner
Yes, you need both of the statement, one actually creats a MSMQ and the other just intializes MSMQ with the pathWhopping
worked like a charm...Hope one of your wishes come true today...You solved a big thing for me today.Tinner
Thanks for the sample. Note that you can directly use the return value of Create: messageQueue = MessageQueue.Create(@".\Private$\SomeTestName");Joijoice
Small typo: messageQueue = new MessageQueue(@".\Private$\SomeTestName"); System.Messaging.Message[] messages = queue.GetAllMessages(); SHould be messageQueue = new MessageQueue(@".\Private$\SomeTestName"); System.Messaging.Message[] messages = messageQueue.GetAllMessages();Tetragrammaton
Hi.. I tried the above code in windows service. Everything works fine except that I am unable to open the queue via Computer management. It says ** The List of messages cannot be retrieved Error: Access Denied** I used 'serviceProcessInstaller.Account = ServiceAccount.LocalSystem;' in my service installer and I logged in as Administrator in the machine.Browder
@Browder Try running the windows service under a different service name. Right click on the service, "Properties", then select "Log On". let me know how it goes.Desquamate
To print the output of the queue to the console, in the body of the output loop, add "message.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" });Console.Write(message.Body.ToString());". As MSMQ passes things around as serialized objects, you have to tell it how to deserialize the objects its received into their original form.Desquamate
#29226101Sputter
@Desquamate Your example should be part of the answer, it's pretty critical and kinda hard to figure out.Fi
R
16

Perhaps code below will be useful for someone to just get quick intro to MSMQ.

So to start I suggest that you create 3 apps in a solution:

  1. MessageTo (Windows Form) Add 1 button.
  2. MessageFrom (Windows Form) Add 1 richtextbox.
  3. MyMessage (Class Library) Add 1 class.

Just copy past code and try it. Make sure that MSMQ is installed on your MS Windows and projects 1 and 2 have reference to System.Messaging.

1. MessageTo (Windows Form) Add 1 button.

using System;
using System.Messaging;
using System.Windows.Forms;

namespace MessageTo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            #region Create My Own Queue 

            MessageQueue messageQueue = null;
            if (MessageQueue.Exists(@".\Private$\TestApp1"))
            {
                messageQueue = new MessageQueue(@".\Private$\TestApp1");
                messageQueue.Label = "MyQueueLabel";
            }
            else
            {
                // Create the Queue
                MessageQueue.Create(@".\Private$\TestApp1");
                messageQueue = new MessageQueue(@".\Private$\TestApp1");
                messageQueue.Label = "MyQueueLabel";
            }

            #endregion

            MyMessage.MyMessage m1 = new MyMessage.MyMessage();
            m1.BornPoint = DateTime.Now;
            m1.LifeInterval = TimeSpan.FromSeconds(5);
            m1.Text = "Command Start: " + DateTime.Now.ToString();

            messageQueue.Send(m1);
        }
    }
}

2. MessageFrom (Windows Form) Add 1 richtextbox.

using System;
using System.ComponentModel;
using System.Linq;
using System.Messaging;
using System.Windows.Forms;

namespace MessageFrom
{
    public partial class Form1 : Form
    {
        Timer t = new Timer();
        BackgroundWorker bw1 = new BackgroundWorker();
        string text = string.Empty;

        public Form1()
        {
            InitializeComponent();

            t.Interval = 1000;
            t.Tick += T_Tick;
            t.Start();

            bw1.DoWork += (sender, args) => args.Result = Operation1();
            bw1.RunWorkerCompleted += (sender, args) =>
            {
                if ((bool)args.Result)
                {
                    richTextBox1.Text += text;
                }
            };
        }

        private object Operation1()
        {
            try
            {
                if (MessageQueue.Exists(@".\Private$\TestApp1"))
                {
                    MessageQueue messageQueue = new MessageQueue(@".\Private$\TestApp1");
                    messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(MyMessage.MyMessage) });


                    System.Messaging.Message[] messages = messageQueue.GetAllMessages();

                    var isOK = messages.Count() > 0 ? true : false;
                    foreach (System.Messaging.Message m in messages)
                    {
                        try
                        {
                            var command = (MyMessage.MyMessage)m.Body;
                            text = command.Text + Environment.NewLine;
                        }
                        catch (MessageQueueException ex)
                        {
                        }
                        catch (Exception ex)
                        {
                        }
                    }                   
                    messageQueue.Purge(); // after all processing, delete all the messages
                    return isOK;
                }
            }
            catch (MessageQueueException ex)
            {
            }
            catch (Exception ex)
            {
            }

            return false;
        }

        private void T_Tick(object sender, EventArgs e)
        {
            t.Enabled = false;

            if (!bw1.IsBusy)
                bw1.RunWorkerAsync();

            t.Enabled = true;
        }
    }
}

3. MyMessage (Class Library) Add 1 class.

using System;

namespace MyMessage
{
    [Serializable]
    public sealed class MyMessage
    {
        public TimeSpan LifeInterval { get; set; }

        public DateTime BornPoint { get; set; }

        public string Text { get; set; }
    }
}

Enjoy :)

Rianon answered 13/5, 2016 at 13:23 Comment(2)
MSQueue thread-safe ? Multiple EXE apps using the same MSQueue ? Whats about GetAllMessages and Purgue ?Weissmann
@Weissmann quora.com/… I hope it will help youRianon

© 2022 - 2024 — McMap. All rights reserved.