Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

How to write to and read from Microsoft Message Queue Server in Visual Basic 2005 or in Visual Basic .NET


View products that this article applies to.

This article was previously published under Q315698

↑ Back to the top


Summary

This article describes how to create a message and send it to Microsoft Message Queue Server in a Windows application. This article also describes how to read from a private queue and to deserialize the message contents for display.

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Windows 2000 Professional (or Server), or Windows XP Professional (or Server), with Microsoft Message Queue Server installed. Microsoft Message Queue Server is included as an option on the four operating systems.
This article assumes that you are familiar with the following topics:
  • Microsoft Message Queue Server
  • The use of tools from the command prompt

Writing to and reading from Microsoft Message Queue Server

The System.Messaging namespaces in the Microsoft .NET Framework have the classes that are required to read from and write to Microsoft Message Queue Server. Follow these steps to create a small Windows application that mimics an online bill payment system:
  1. Start Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET.
  2. Create a new Windows application in Visual Basic 2005 or in Visual Basic .NET, and then name it MSMQ.
  3. If the the Solution Explorer is not displayed, press CTRL+ALT+L to display it.
  4. In the Solution Explorer, right-click References, and then select Add Reference. On the .NET tab, find the System.Message.dll file in the list of .dll files. Click Select to select the file, and then click OK.

    Note In Visual Studio 2005, you do not have to click Select.
  5. Form1.vb now is open in Design view. If it is not open, double-click Form1.vb in the Solution Explorer.
  6. Press CTRL+ALT+X to open the toolbox. In the toolbox, select Windows Forms. (In Visual Studio 2005, select All Windows Forms.) Select and drag the following to the middle of the form: four rows each of a Label followed by a Textbox (positioned to the right of each label). Under these, add two Buttons. Press F4 to access the Property page for each control. Change the Text Property for the labels to the following (in order):
    • Pay To:
    • Your Name:
    • Amount:
    • Due Date:
    Change the text on the first Button to Send Payment, and then change the text on the second Button to Process Payment.
  7. Add two Imports statements above the class declaration to include the additional classes that reside in the System.Messaging and System.Text namespaces. The System.Text namespace is for the use of the StringBuilder class, a new .NET Framework class that it is best to use when you concatenate strings:
    Imports System.Messaging
    Imports System.Text
    						
  8. This application works with a private queue that you must first create in the Computer Management console. On the desktop, right-click My Computer, and then click Manage. Expand Services and Applications to find Message Queuing.

    Note If you do not find Message Queuing, Message Queue Server is not installed.

    Right-click Private Queues, point to New, and then click Private Queue. Name the queue billpay. Leave the Computer Management console open, because you return to it later to view messages. Do not select the Make Queue Transactional check box.
  9. As mentioned earlier in this article, this sample application mimics an online bill payment service. Therefore, create a structure that contains variables to hold the data that defines a payment:
    Public Structure Payment
    Public Payor As String
    Public Payee As String
    Public DueDate As Date
    Public Amount As Integer
    End Structure
    					
  10. Click the Form1.vb (Design) tab above the editor window to return to Design view. Double-click the Send Payment button. The insertion point is now in the Button1_Click event handler in Form1.vb. The first task in this routine is to set the properties of the structure to values of the form elements:
          Dim myPayment As Payment
          With myPayment
          	.Payor = TextBox1.Text
          	.Payee = TextBox2.Text
          	.Amount = CInt(TextBox3.Text)
          	.DueDate = CType(TextBox4.Text, Date)
          End With
    					
  11. Create an instance of the Message class, and then set the Body property to the payment structure:
    Dim msg As Message = New Message()
    msg.Body = myPayment
    					
  12. To send a message to Microsoft Message Queue Server, the last step is to create an instance of the MessageQueue class and to call the Send method, passing in the Message object. The MessageQueue class is the wrapper that manages the interaction with Microsoft Message Queue Server.

    Note the syntax for setting the path to the private queue that you created in the Computer Management console. Private queues take the form machinename\Private$\queuename. Localhost machines are referenced with a . (a dot or period).
    Dim msgQ As New MessageQueue(".\Private$\billpay")
    msgQ.Send(msg)
    						
    The code is now in place to send a message to Microsoft Message Queue Server. The .NET Framework automatically serializes the message by using an XMLMessageFormatter object, which is implicitly created when sending messages.
  13. Create another Button Click event handler for Button2, which receives and "processes" the payment message that is sent in the Button1 event handler. The first line is the same as the one that you just saw in the first event handler:
    Dim msgQ As New MessageQueue(".\Private$\BillPay")
    					
  14. Create an array of types to pass to the XMLMessageFormatter class. Note that this class must be explicitly created when receiving messages. Its constructor takes either a string array of type names or, more preferably, a Type array of types:
    Dim arrTypes(1) As System.Type
    arrTypes(0) = GetType(Payment)
    arrTypes(1) = GetType(Object)
    msgQ.Formatter = New XmlMessageFormatter(arrTypes)
    Dim myPayment As Payment = CType(msgQ.Receive.Body, Payment)
    						
    These types tell the XMLMessageFormatter how to deserialize the message.
  15. Messages are received by calling the Receive method. Access the Body property to read the message contents. This property returns an object, so it must be cast to the payment type to retrieve the contents in a usable form:
            	Dim sb As New StringBuilder()
            	sb.Append("Payment paid to: " & myPayment.Payor)
            	sb.Append(vbCrLf)
            	sb.Append("Paid by: " & myPayment.Payee)
            	sb.Append(vbCrLf)
            	sb.Append("Amount: $" & myPayment.Amount.ToString)
            	sb.Append(vbCrLf)
            	sb.Append("Due Date: " & myPayment.DueDate.ToShortDateString)
    					
  16. Create a message box to display the results:
    MessageBox.Show(sb.ToString, "Message Received!")
    					

Complete code listing (Form1.vb)

Imports System.Messaging
Imports System.Text

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call.

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents TextBox3 As System.Windows.Forms.TextBox
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Friend WithEvents Label4 As System.Windows.Forms.Label
    Friend WithEvents TextBox4 As System.Windows.Forms.TextBox

    'Required by the Windows Form Designer.
    Private components As System.ComponentModel.Container

    'NOTE: The following procedure is required by the Windows Form Designer.
    'It can be modified by using the Windows Form Designer.  
    'Do not modify it by using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.TextBox1 = New System.Windows.Forms.TextBox
        Me.Label1 = New System.Windows.Forms.Label
        Me.TextBox2 = New System.Windows.Forms.TextBox
        Me.Label2 = New System.Windows.Forms.Label
        Me.TextBox3 = New System.Windows.Forms.TextBox
        Me.Label3 = New System.Windows.Forms.Label
        Me.Label4 = New System.Windows.Forms.Label
        Me.TextBox4 = New System.Windows.Forms.TextBox
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(104, 160)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(88, 23)
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Send Payment"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(96, 200)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(104, 23)
        Me.Button2.TabIndex = 3
        Me.Button2.Text = "Process Payment"
        '
        'TextBox1
        '
        Me.TextBox1.Location = New System.Drawing.Point(128, 46)
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.TabIndex = 2
        Me.TextBox1.Text = ""
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(71, 48)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(48, 23)
        Me.Label1.TabIndex = 4
        Me.Label1.Text = "Pay To:"
        '
        'TextBox2
        '
        Me.TextBox2.Location = New System.Drawing.Point(128, 72)
        Me.TextBox2.Name = "TextBox2"
        Me.TextBox2.TabIndex = 2
        Me.TextBox2.Text = ""
        '
        'Label2
        '
        Me.Label2.Location = New System.Drawing.Point(52, 74)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(72, 23)
        Me.Label2.TabIndex = 4
        Me.Label2.Text = "Your Name:"
        '
        'TextBox3
        '
        Me.TextBox3.Location = New System.Drawing.Point(128, 96)
        Me.TextBox3.Name = "TextBox3"
        Me.TextBox3.TabIndex = 2
        Me.TextBox3.Text = ""
        '
        'Label3
        '
        Me.Label3.Location = New System.Drawing.Point(70, 99)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(48, 23)
        Me.Label3.TabIndex = 4
        Me.Label3.Text = "Amount:"
        '
        'Label4
        '
        Me.Label4.Location = New System.Drawing.Point(60, 124)
        Me.Label4.Name = "Label4"
        Me.Label4.Size = New System.Drawing.Size(59, 23)
        Me.Label4.TabIndex = 4
        Me.Label4.Text = "Due Date:"
        '
        'TextBox4
        '
        Me.TextBox4.Location = New System.Drawing.Point(128, 120)
        Me.TextBox4.Name = "TextBox4"
        Me.TextBox4.TabIndex = 2
        Me.TextBox4.Text = ""
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.AddRange(New System.Windows.Forms.Control() _
            {Me.Label4, Me.TextBox4, Me.TextBox3, Me.Label3, _
             Me.TextBox2, Me.Label2, Me.Label1, Me.Button2, _
             Me.TextBox1, Me.Button1})
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Public Structure Payment
        Public Payor As String
        Public Payee As String
        Public DueDate As Date
        Public Amount As Integer
    End Structure

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        Dim myPayment As Payment
        With myPayment
            .Payor = TextBox1.Text
            .Payee = TextBox2.Text
            .Amount = CInt(TextBox3.Text)
            .DueDate = CType(TextBox4.Text, Date)
        End With

        Dim msg As Message = New Message
        msg.Body = myPayment

        Dim msgQ As New MessageQueue(".\Private$\BillPay")
        msgQ.Send(msg)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button2.Click

        Dim msgQ As MessageQueue = New MessageQueue(".\Private$\BillPay")
        Dim arrTypes(1) As System.Type

        arrTypes(0) = GetType(Payment)
        arrTypes(1) = GetType(Object)

        msgQ.Formatter = New XmlMessageFormatter(arrTypes)

        Dim myPayment As Payment = CType(msgQ.Receive.Body, Payment)

        Dim sb As New StringBuilder
        sb.Append("Payment paid to: " & myPayment.Payor)
        sb.Append(vbCrLf)
        sb.Append("Paid by: " & myPayment.Payee)
        sb.Append(vbCrLf)
        sb.Append("Amount: $" & myPayment.Amount.ToString)
        sb.Append(vbCrLf)
        sb.Append("Due Date: " & myPayment.DueDate.ToShortDateString)

        MessageBox.Show(sb.ToString, "Message Received!")

    End Sub
End Class
				
Note You must change the code in Visual Basic 2005. By default, Visual Basic creates two files for the project when you create a Windows Forms project. If the form is named Form1, the two files that represent the form are named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file. The Windows Forms Designer writes the code in the Form1.Designer.vb file. The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This behavior prevents the designer-generated code from being interspersed with your code.

For more information about partial classes and the Windows Forms Designer, visit the following Microsoft Developer Network (MSDN) Web site:

Verification

  1. Press F5 to run the application in Debug mode.
  2. Type values in each TextBox, and then click Send Payment.
  3. Press ALT+TAB to return to the Computer Management console. Click the Queue messages folder in Private Queues under billpay, and then verify that Microsoft Message Queue Server received a message (indicated by an envelope icon). Right-click the message, select Properties, and then click the Body tab to check the message.

    Note The contents of the payment message are serialized as XML.
  4. Press ALT+TAB to return to the bill payment Windows application. Click the Process Payment button. You see a message box that confirms the receipt of a message and displays the message text.

Troubleshooting

  • Forgetting to create a private queue is usually an issue only on Windows 2000 Professional and Windows XP Professional. Windows 2000 Server and Windows Server 2003 permit the use of the public queue.
  • Passing the correct arguments to the XMLMessageFormatter() can be tricky. In this example, exceptions are thrown if either the object or the Payment Types are not included in the Type array that is passed to the constructor.

REFERENCES

For more information about Microsoft Message Queue Server, visit the following Microsoft Web sites:

↑ Back to the top


Keywords: kbvs2005swept, kbvs2005applies, kbhowtomaster, KB315698

↑ Back to the top

Article Info
Article ID : 315698
Revision : 11
Created on : 12/30/2006
Published on : 12/30/2006
Exists online : False
Views : 665