|Programming with MSMQ|
Using the COM interface of the MSMQ object can be a bit confusing, but once you're exposed to it, it is relatively easy to work with. One step to keep in mind is setting up the Message Queue Server. I won't address the specifics here (information for MSMQ setup can be found in the Windows 2000 help files), but there are some helpful pointers to remember when reading and writing to the queue that I will address. The Message queue best runs when installed on the Primary Domain Controller. There are other options, but I have not experimented with them yet. Once the queue is setup, there is little maintainance. There are several options that may be catered to your needs, but the default ones should suffice. If you are not going to run your application on the PDC, you need to have an independent or dependent client setup on your machine. One feature that cannot be used on a dependent client is the use of transactional queues. If you are running your application on a dependent client, you may only use non-transactional queues. Creating the queue is simple (View code below). One thing that might throw you for a loop is if your queue already exists when you try to create it. The .Create method of the MSMQ.MSMQQueueInfo object does not have a parameter to overwrite the existing queue or leave it alone and proceed, it will raise an error if the queue already exists. You simply just handle the error (which is referenced below) and proceed. Opening the queue for sending is straight forward, but when opening the queue for receive access, you must use a share mode of MQ_DENY_NONE. Any other share mode will not work. Another tip when opening a queue for receive access is to use the ReceiveCurrent method and not the Receive method. MSMQ uses uses a cursor to keep track of the current message. The ReceiveCurrent takes advantage of this and it helps to prevent possible errors. One method that is not available to the MSMQ COM object is purging. Purging can only be done manually from within the MSMQ application or via an API call: Declare Function MQPurgeQueue Lib "mqrt.dll" (ByVal hQueue As Long) As Long The constants used in this example are readily available in VB's Object Browser.
Public Sub MSMQExample On Error GoTo ErrorHandler 'QueueInfo object Dim qInfo As MSMQ.MSMQQueueInfo 'Queue object Dim qQueue As MSMQ.MSMQQueue 'Message object Dim qmessage As MSMQ.MSMQMessage Dim lBody As Long Set qInfo = New MSMQ.MSMQQueueInfo 'Creating the queue ------------------- 'create queue With qInfo .PathName = Server\Queue Name .Label = Queue Label 'Creates an non-transactional, universally readable queue 'If the queue already exists, you will need to handle the error (see ErrorHandler below) Call .Create(False, True) End With 'Populating the queue --------------------- 'Code for Declaring and Opening a recordset ' ' ' 'open queue with send access Set qQueue = qInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE) If qQueue.IsOpen Then Do Until rs.EOF lBody = CLng(rs.Fields("EmployerID").Value) 'create message Set qmessage = New MSMQ.MSMQMessage 'assign body of message qmessage.Body = CLng(lBody) 'sending the message to the queue qmessage.Send qQueue 'destroy message Set qmessage = Nothing 'get next record rs.MoveNext Loop 'close queue qQueue.Close End If 'Code for Closing and Destroying a recordset ' ' ' 'Reading messages from the queue -------------------------------- 'Open Queue with receive access Set qQueue = qInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE) If qQueue.IsOpen Then 'get first message from queue Set qmessage = qQueue.ReceiveCurrent(MQ_NO_TRANSACTION, , , receivetimeout:=20) Do Until qmessage Is Nothing 'get contents of message lBody = qmessage.Body 'Process message body data here ' ' ' 'destroy message Set qmessage = Nothing 'get next message from queue Set qmessage = qQueue.ReceiveCurrent(MQ_NO_TRANSACTION, , , receivetimeout:=20) Loop 'close queue qQueue.Close End If 'cleanup Set qQueue = Nothing set qInfo = Nothing Exit Sub ErrorHandler: If Err.Number = MQ_ERROR_QUEUE_EXISTS Then Err.Clear 'queue already exists Resume Next End If
Freeware! This add-in gives you some great extra features when working in VB6. It has a tab index setter, options to add a chunk of error handling code, a simple code analyzer that gives you some metrics, and my favorite - an option to identify unused code and variables. If you're still using VB6 it's worth trying.