Visual Basic Code Example: Matching Acknowledgment Messages


Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

This example provides two Sub procedures: a private Sub procedure that searches an administration queue for the acknowledgment message that was returned as a result of sending a specific message, and a second helper procedure that is used to compare two variants.

This example assumes that the message was sent to a single destination queue, so it compares only the returned message identifier in the MSMQMessage.CorrelationId property of the acknowledgment message to the cached identifier of the message that was sent. For details on other information that is returned in the message properties of an acknowledgment message, see Acknowledgment Message Properties.


For cases where the original message was sent to multiple destination queues, this example would need to be modified so that it compares the returned message identifier (MSMQMessage.CorrelationId) and the returned destination queue (MSMQMessage.ResponseQueueInfo) to the cached message identifier and destination queue respectfully. Both pieces of information need to be compared because messages sent to multiple destination queues all have the same message identifier.

To match acknowledgment messages

  1. Declare the objects needed to read the messages in the administration queue.


When declaring the MSMQMessage object when reading messages, you cannot use the New keyword.

  1. Create a direct format name for the queue using the computer and queue name provided by the caller.

  2. Set the MSMQQueueInfo.FormatName property.

  3. Call MSMQQueueInfo.Open to open the queue with receive access. When opening a queue with receive access the application can peek at or retrieve the messages in the queue.

  4. Call MSMQQueue.PeekCurrent to initialize the cursor. This call points the cursor to the first message in the queue.

  5. Using a loop, call VariantCompare to compare the correlation identifier of each acknowledgment message with the message identifier provided by the caller.

  6. When there are no messages left, call MSMQQueue.Close to release resources used to open queue and exit the Sub procedure.

Code Example

The following code example can be run on all versions of Message Queuing.

' A function that compares between two variants.  
Function VariantsCompare( _  
                         var1 As Variant, _  
                         var2 As Variant _  
                         ) As Boolean  
  ' Check if the variants have the same bounds.  
  If LBound(var1) = LBound(var2) And UBound(var1) = UBound(var2) Then  
    ' Compare the variants byte-by-byte.  
    For Counter = LBound(var1) To UBound(var2)  
      If Not var1(Counter) = var2(Counter) Then  
        VariantsCompare = False  
        Exit Function  
      End If  
    Next Counter  
    VariantsCompare = True  
    VariantsCompare = False  
  End If  
End Function  
Private Sub MatchAcknowledgments(strQueueName As String, strComputerName As String, msgReg As MSMQMessage))  
  ' Declare variables.  
  Dim strFormatName As String  
  Dim q As MSMQQueue  
  Dim qinfo As New MSMQQueueInfo  
  Dim msgAck As MSMQMessage  
  ' Create a direct format name.  
  strFormatName = "DIRECT=OS:" & strComputerName & "\" & strQueueName  
  ' Set the format name of the MSMQQueueInfo object.  
  On Error GoTo ErrorHandler  
  qinfo.FormatName = strFormatName  
  ' Open the queue with receive access.  
  Set q = qinfo.Open(Access:=MQ_RECEIVE_ACCESS, ShareMode:=MQ_DENY_NONE)  
  ' Peek at messages in the queue using the cursor, and look for the requested acknowledgment.  
  Set msgAck = q.PeekCurrent(ReceiveTimeout:=1000)  
  Do While Not msgAck Is Nothing  
    ' Compare between the identifier of the given message and the   
    ' correlation ID of the peeked at message.  
    If VariantsCompare(msgAck.CorrelationId, msgReg.Id) Then  
      MsgBox "An acknowledgment message was found.", , "Message: " & msgAck.Label  
      Exit Do  
      Set msgAck = q.PeekNext(ReceiveTimeout:=1000)  
    End If  
  ' If all the messages were peeked at, and no acknowledgment was found.  
  If msgAck Is Nothing Then  
    MsgBox "An acknowledgment message was not found."  
  End If  
  ' Close the queue.  
  Exit Sub  
  MsgBox "Error " + Hex(Err.Number) + " was returned." _  
         + Chr(13) + Err.Description  
  If Not q Is Nothing And q.IsOpen2 Then  
End Sub