New to compact framework tutorials? Learn to write your first compact framework application here.
Zac Efron - Hairspray star and Mythbusters' Kari Byron at Celebrity Treat. Check out income and career information in Singapore.

Saturday, January 07, 2006

- MSMQ Message Queueing in Compact Framework (part 1)

In this tutorial, we write a simple MSMQ application for a Windows Mobile device. The application automatically installs the MSMQ service if it's not already present. A simple interface is provided to let the user send and receive messages via MSMQ.



MSMQ is a Microsoft message queueing technology that allows disparate applications, not necessarily running in the same machine, to send messages to one another. Part of this store-and-forward technology is a failsafe mechanism to ensure guaranteed delivery (well, to an extent). Message priorities can also be set as well.

One of the strongest competitors to Microsoft, in terms of providing message queueing middleware, remains to be IBM, which offers the product called WebSphere MQ (previously called IBM MQSeries).

This tutorial is based on Mark Ihimoyan's posts in his excellent blog.
  1. As usual, start Visual Studio and create a new smart device project.
  2. In Solution Explorer, right-click on References, and add the reference to System.Messaging component. We need this reference as we are using the Messaging classes later.
  3. Change the form property MinimizeBox to false, so that the use can close the application easily.
  4. Add a TextBox, 2 Buttons and a Label to the form, naming them txtSendMsg, btnSend, btnReceive and lblReceiveMsg respectively. The first button lets the user send the message in the textbox to a message queue. The second button receives a message from the queue. Even if the user closes the application, the stored messages in the queue remain intact and can be received when the application is restarted (however, a soft reset clears the queue).
  5. Next, we want to make the application self-contained, in that it will check for the presence of the MSMQ service and automatically installs it if it is not detected.
  6. Go to Microsoft Mobile Development Center and follow the link "Redistributable Server Components for Windows Mobile 5.0" to download the package. We need the msmq.ARM.CAB file in the package.
  7. After downloading, extract the msmq.ARM.CAB file (under msmq folder in the downloaded package). This is the cab file that installs the MSMQ service in the device.
  8. Back in Visual Studio, right-click on your project in Solution Explorer and add msmq.ARM.CAB to your project (use Add-> Existing Item...). Then click on msmq.ARM.CAB in Solution Explorer and change its "Copy to Output Directory" property to "Copy if newer". This will ensure that the cab file is copied over to the program folder in the device.
  9. In your form code, import the namespaces:
  10. using System.IO;
    using System.Messaging;
    using System.Runtime.InteropServices;
  11. Then within the form partial class, add the following declarations needed to P/Invoke the CreateProcess Win32 function. We need to call CreateProcess to install the cab.
  12. public class ProcessInfo
    {
      public IntPtr hProcess;
      public IntPtr hThread;
      public Int32 ProcessId;
      public Int32 ThreadId;
    }

    [DllImport("CoreDll.DLL", SetLastError = true)]
    private extern static
        int CreateProcess(String imageName,
        String cmdLine,
        IntPtr lpProcessAttributes,
        IntPtr lpThreadAttributes,
        Int32 boolInheritHandles,
        Int32 dwCreationFlags,
        IntPtr lpEnvironment,
        IntPtr lpszCurrentDir,
        IntPtr lpsiStartInfo,
        ProcessInfo pi);
    [DllImport("CoreDll.dll")]
    private extern static  Int32 GetLastError();

    [DllImport("CoreDll.dll")]
    private extern static
        Int32 GetExitCodeProcess(IntPtr hProcess, out Int32 exitcode);

    [DllImport("CoreDll.dll")]
    private extern static
         Int32 CloseHandle(IntPtr hProcess);

    [DllImport("CoreDll.dll")]
    private extern static
        IntPtr ActivateDevice(
          string lpszDevKey,
            Int32 dwClientInfo);

    [DllImport("CoreDll.dll")]
    private extern static
        Int32 WaitForSingleObject(IntPtr Handle,
        Int32 Wait);

    public static bool CreateProcess(String ExeName, String CmdLine)
    {
      Int32 INFINITE;
      unchecked { INFINITE = (int)0xFFFFFFFF; }
      ProcessInfo pi = new ProcessInfo();
      if (CreateProcess(ExeName, CmdLine, IntPtr.Zero, IntPtr.Zero,
          0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, pi) == 0)
      {
        return false;
      }
      WaitForSingleObject(pi.hProcess, INFINITE);
      Int32 exitCode;
      if (GetExitCodeProcess(pi.hProcess, out exitCode) == 0)
      {
        MessageBox.Show("Failure in GetExitCodeProcess");
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return false;
      }
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      if (exitCode != 0)
        return false;
      else
        return true;
    }
  13. In the Form Load event handler (remember to generate the event handler stub by double-clicking on the form in design mode; similarly for the button click event handlers later), enter the following code which checks for and installs the MSMQ service.
  14. string MSMQ_ADM = @"\windows\msmqadm.exe";
    if (!CreateProcess(MSMQ_ADM, "status"))
    {
      if (!File.Exists(MSMQ_ADM) ||
         !File.Exists(@"\windows\msmqd.dll") ||
         !File.Exists(@"\windows\msmqrt.dll"))
      {
        //install msmq
        string _path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        string docname = _path + "\\msmq.ARM.CAB";
        CreateProcess("wceload.exe", "/noui \"" + _path + "\\msmq.ARM.CAB\"");
      }
      //check again
      if (!File.Exists(@"\windows\msmqadm.exe"))
      {
        MessageBox.Show("failed to install msmq cab");
        Close();
      }
      else //register, start and activate service
      {
        CreateProcess(MSMQ_ADM, "register cleanup");
        if (CreateProcess(MSMQ_ADM, "register install")
          && CreateProcess(MSMQ_ADM, "register")
          && CreateProcess(MSMQ_ADM, "enable binary"))
        {
          IntPtr handle = ActivateDevice(@"Drivers\BuiltIn\MSMQD", 0);//device registry key
          CloseHandle(handle);
          if (CreateProcess(MSMQ_ADM, "status")) return; //success
        }
        MessageBox.Show("failed to start msmq");
        Close();
      }
    }
  15. In the btnSend click event handler, enter the following code to send a message to the "testq" queue.
  16. if (txtSendMsg.Text.Trim() == "") return;
    string strDestQ = @".\private$\testq"; //queue name
    try
    {
      if (!MessageQueue.Exists(strDestQ))
        MessageQueue.Create(strDestQ);
      MessageQueue mq = new MessageQueue(strDestQ);
      mq.Send(txtSendMsg.Text);
      txtSendMsg.Text = "";
    }
    catch { }
  17. Finally, in the btnReceive click event handler, we will receive the frontmost message in the "testq" queue. Note that we are setting a simple timeout of 1 second (so the UI is not blocked for too long) in case there isn't any message in the queue.
  18. lblReceiveMsg.Text = ""; Refresh();
    MessageQueue mq = new MessageQueue(@".\private$\testq");
    //set formatter for deserializing message
    mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
    try
    {
      Message messageReceived = mq.Receive(new TimeSpan(0, 0, 1));//timeout in 1s
      lblReceiveMsg.Text = (string)messageReceived.Body;
    }
    catch { lblReceiveMsg.Text = "- timeout -"; }
  19. We are done! Deploy and run. The first time you run, there is quite a long delay on form load, as the application is invoking wceload.exe to install the MSMQ service. When the form is loaded, type something in the textbox and click the Send button. Send a few more messages. Then click the Receive button a few times.
  20. Try closing and reopening the application and test if sent messages are still receivable. What about the effect of doing a soft reset?
In part 2, coming soon, we will send MSMQ messages across the network. Watch this space.

Categories: [MSMQ_] [Networking_] Tags: [] [] [] []

30 Comments:

Blogger Kaiser Soze said...

Hi netcf2,

To generate categories for my stock market blog, I used your method of tagging posts and then using google search to locate them.

The method has worked out very well. So thank you very much.

Kaiser

1/07/2006  
Blogger danchong said...

hi Kaiser, thanks for the support! I believe you are referring to my post here.

1/07/2006  
Blogger Fay said...

Posted categories from your Nov. post, working good. Question on how you post such short post and link to them with read more. How do you do that? Thanks, great blog.

1/18/2006  
Blogger danchong said...

hi faith, to do a "read more" hack, you have to use the HTML span tag and hide the text. View my HTML source and see if you can figure it out. It should be quite easy if you're familiar with HTML.

1/22/2006  
Anonymous Anonymous said...

Hi,

Can use this message queue with a C++ message queue on the other side.

like I want create a message queue in c# programe and coomunicate with a process which is written in C++.

Is this possible, if yes how.

regards
krishna

6/14/2006  
Blogger danchong said...

hi Krishna, I haven't tried communicating with a C++ queue. But as far as I understand it, MSMQ allows disparate processes to communicate seamlessly, as long as the processes adhere to the MSMQ protocol. Whether a process is written using C# or C++ shouldn't matter.

6/15/2006  
Anonymous Anonymous said...

You speak about extracting the CAB file, but I can't seem to figure this simple step out... Any pointers for this

8/23/2006  
Blogger danchong said...

Hi Warren,

The URL which I gave above doesn't contain the link "Redistributable Server Components for Windows Mobile 5.0" anymore.

However, you can still get the package by doing a Google search for the phrase "Redistributable Server Components for Windows Mobile 5.0". In the Google results, one of the top results (most likely the first link) should lead you to a Microsoft download page where you can download the said package.

11/13/2006  
Anonymous Anonymous said...

Excellant tutorial on how to use create process! Thank you so much! BrandonBlais@juno.com

3/09/2007  
Anonymous Anonymous said...

Excellent tutorial on MSMQ but i would like to know that this application is restricted to single Device or there it is distributed.
If it applicable to single device, then please let me know how to make it to the send & receive SMS frm different smart devices.

Amit Kumar Rana
email- complete.amit@gmail.com

3/10/2007  
Blogger Free eBooks said...

Some good ebooks on microsoft .net compact framework kick start 2005 compact framework ebooks

6/10/2007  
Blogger Prajeesh Prathap said...

Hi,

The tutorial was very helpful for me to create an application using MSMQ to upload data into a server.
But the data i uploaded was is not getting reflected in the remote private queue

Pls help me to solve this issue.

i am putting the code which i used for uploading the data into the server.


Public Sub SendToQueue()

Dim remoteQueue As Messaging.MessageQueue = New System.Messaging.MessageQueue
remoteQueue.DefaultPropertiesToSend.Priority = System.Messaging.MessagePriority.VeryHigh
remoteQueue.Formatter = New System.Messaging.XmlMessageFormatter(New String(-1) {})
Dim lsMSMQPath As String
Dim AppPath As String = IO.Path.GetDirectoryName( _
Reflection.Assembly.GetExecutingAssembly.GetName.CodeBase.ToString())


Dim _deviceIPAddress As String = String.Empty
Dim localHostName As String = Net.Dns.GetHostName()
Dim iphe As Net.IPHostEntry = Net.Dns.GetHostEntry(localHostName)
Dim ipAddr As String = String.Empty
For Each addr As Net.IPAddress In iphe.AddressList
ipAddr = addr.ToString()
Next
_deviceIPAddress = ipAddr



lsMSMQPath = "FormatName:DIRECT=OS:ServerName\private$\PrivateQueueName;XACTONLY"

remoteQueue.Path = lsMSMQPath


Dim responseQueue As messaging.messageQueue = New Messaging.MessageQueue
Dim adminQueue As messaging.messageQueue = New Messaging.MessageQueue
responseQueue.Path = String.Format(System.Globalization.CultureInfo.InvariantCulture, "FormatName:Direct=TCP:{0}\private$\MyResponse", _deviceIPAddress)
adminQueue.Path = String.Format(System.Globalization.CultureInfo.InvariantCulture, "FormatName:Direct=TCP:{0}\private$\MyAdmin", _deviceIPAddress)



Dim msg As Message = New Message
msg.Body = "My data"
msg.Label = "My Label"
msg.TimeToBeReceived = System.TimeSpan.Parse("1.00:00:00")
msg.TimeToReachQueue = System.TimeSpan.Parse("1.00:00:00")
msg.ResponseQueue = responseQueue
msg.AdministrationQueue = adminQueue
msg.AcknowledgeType = Messaging.AcknowledgeTypes.FullReceive Or Messaging.AcknowledgeTypes.FullReachQueue
msg.UseDeadLetterQueue = True
msg.UseJournalQueue = True
remoteQueue.Send(msg, Messaging.MessageQueueTransactionType.Single)
End Sub


the code is throwing no error after sending the data to the queue.
But the data is not reflected.

I am able to send data to a remote private queue in my network. But not to a remote computer on the public network.

7/13/2007  
Blogger danchong said...

>I am able to send data to a remote private queue in my network. But not to a remote computer on the public network.

My guess is that certain networking ports required for MSMQ are blocked between your private network and the wider network.

See:
http://support.microsoft.com/kb/178517

7/13/2007  
Blogger Prajeesh Prathap said...

You are correct Dan,
We released some ports and it started working fine. Now i have a problem in formatting. Is there any way to implement ActiveXFormatting for .NET CF Message. My server code that reads the messages from the queue expects the message in ActiveXFormatting.


Thank you for the help and time you spend for helping me.

7/16/2007  
Blogger danchong said...

Unfortunately, I haven't got the chance to explore ActiveXFormatting. Maybe this article will help:
http://msdn.microsoft.com/msdnmag/issues/03/12/MSMQandNET/

7/17/2007  
Anonymous Anonymous said...

Is this same with this one ?

7/17/2007  
Blogger Prajeesh Prathap said...

Hi All,

I have a MQ in a windows 2000 terminal to which i upload my messages. But when i tried to create a trigger on the MQ. it gave me a warning "The queue path was not validated, Make sure that the queue exists and that it allows everyone Peek Access". I have provided full access to everyone and also write access to Anonymous Login. The problem is my trigger is not invoked once the message reaches the Queue. I have created a Trigger that invokes a COM+ component and it is registered using REGSVCS...

Can somebody help me to fix this issue / or is there any other options to invoke a trigger when a message reaches the queue.

7/24/2007  
Blogger Jovis Low said...

Your blog is great and I have learn a lot from your experience.

Hope we can share our knowledge.


Thank you very much.


Best regards,

Jovis
http://prgexp.blogspot.com

4/22/2008  
Blogger akswift said...

Hi there,
nice Article.

Is there any possibility to change the path of the temp folder?

I have a device which often gets hard resetet. So i want to have the messages on a folder which then isn't deleted

9/19/2008  
Blogger Unknown said...

i think this article was a great. easy to follow.

Download free ebooks at http://www.ebook-x.com

10/14/2008  
Anonymous kerja keras adalah energi kita said...

Thanks for the tips,..

11/13/2009  
Blogger Hadyan Mardhi Fadlillah said...

Good Tutorial
Nice Info, I like your blog.

keep update !!

visit this site: http://wartawarga.gunadarma.ac.id

6/02/2010  
Anonymous Competitions said...

An informative post.it is good.

4/06/2011  
Anonymous Business Directory said...

It is a good tutorial for windows device users.
you did good job.Keep it up.

4/06/2011  
Anonymous muebles en barcelona said...

It can't really work, I suppose like this.

11/28/2011  
Blogger ChoiBlogs.blogspot.com said...

thanks post !!!!!!!!!

12/30/2011  
Blogger Unknown said...

One of my favourite post and very knowledgeable post
High Profile mumbai escorts

6/02/2017  
Blogger rosemary said...

I Saw Your Website Carefully. Thanks For Create Such Kind Of Informative Website. Your All Content Is Relevant To Your Subject. I Say Keep It Continue, Because Your Website And Subject Is Meaningful For The Users. I Have Recommended Your Website With My Friends Also.
I Am Ritu Sharma. I Am An Independent Mumbai Escort Girl. I Deal In Mumbai Escorts Service. I Am Very Hot And Sexy. Being A Mumbai Escort Girl I Have Five Years’ Experience. That’s Why I Understand The Each Personal Needs Of My Every Client. My Service Charge Is Low And Service Is Super. You Can Avail My VIP Mumbai Escorts Service At Your Home Or In Hotel. I Am Comfortable To Provide Mumbai Escorts Service In Local And Outside Also. Visit www.escortservicemumbai.net Call +91- 9OO4OO9481
Visit The Links Below And Have A Look At My Various Mumbai Escort Services-
Mumbai Escorts
Mumbai Call Girls
Mumbai Escorts In Vile
Parle

Bandra Escorts
Juhu Escorts
Andheri Escorts

Mumbai Escorts In Colaba

3/15/2019  
Blogger Mumbai Model Escorts Agency said...

In Mumbai there many high class men who always nonappearance to profit special treatment. When comes to spending become primeval taking into account gorgeous looking ladies these men always nonappearance to profit several choices. These men always lack to spend erotic period taking into account most classy ladies of Mumbai. Due to this gloss we are offering Mumbai escorts who are having quickly maintained body have an effect on and at the same era these ladies are having harmonious presence of mind. Our escorts can obtain into the mind of our customer and at the associated time cater them escort facilities in the way they nonattendance due to this excuse we are best escort foster provider. Visit at :

πŸ‘‰ Mumbai Escorts

πŸ‘‰ Call Girls In Mumbai

πŸ‘‰ Independent Mumbai Escorts

πŸ‘‰ Mumbai Housewife Escorts

πŸ‘‰ Mumbai Air Hostess Escorts

πŸ‘‰ Russian Escorts In Mumbai

7/15/2020  
Blogger Aisha paal Call Girl in Pune said...

Escorts service in Pune
Pune escorts
Escorts in Pune
Pune escorts

3/10/2021  

Post a Comment

<< Home