Article ID: 315698
Article Last Modified on 12/30/2006
APPLIES TO
- Microsoft Visual Basic 2005
- Microsoft Visual Basic .NET 2003 Standard Edition
- Microsoft Visual Basic .NET 2002 Standard Edition
- Microsoft Windows XP Professional
- Microsoft Windows 2000 Server
- Microsoft Windows 2000 Professional Edition
- Microsoft Windows Server 2003 R2 Datacenter Edition (32-Bit x86)
- Microsoft Windows Server 2003 R2 Enterprise Edition (32-Bit x86)
- Microsoft Windows Server 2003 R2 Standard Edition (32-bit x86)
- Microsoft Windows Server 2003, Datacenter Edition (32-bit x86)
- Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
- Microsoft Windows Server 2003, Standard Edition (32-bit x86)
This article was previously published under Q315698
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:
- Start Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET.
- Create a new Windows application in Visual Basic 2005 or in Visual Basic .NET, and then name it MSMQ.
- If the the Solution Explorer is not displayed, press CTRL+ALT+L to display it.
- 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. - Form1.vb now is open in Design view. If it is not open, double-click Form1.vb in the Solution Explorer.
- 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:
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
- 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. 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
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
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
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.
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")
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.
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)
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
- Press F5 to run the application in Debug mode.
- Type values in each TextBox, and then click Send Payment.
- 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.
- 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:
Keywords: kbvs2005swept kbvs2005applies kbhowtomaster KB315698