Content Supported by Sourcelens Consulting
Attribute VB_Name = "modQueueSupport"
Option Explicit
'--------------------------------------------------
' Contains functions useful for message queues. These functions
' are intended to be called from applications to create, destroy, manage
' and access queues.
'
' [11/10/97, IvoSa] Created
'--------------------------------------------------
'Registry info used to manage Queue IDs, etc.
Global Const regAPPLICATION_NAME = "MessageQueueAdministration"
Global Const regKEY_NAME = "QueueGUID"
Global Const regNOT_FOUND = "<Not Found>"
'Time
Global Const ONE_SECOND = 1000 '1000ms
Global Const FIVE_SECONDS = ONE_SECOND * 5
'Errors that this module may raise
Public Enum QueueErrors
qeNO_QUEUE = 30000
qeBOGUS_GUID = 30001
End Enum
'--------------------------------------------------
'Opens a message queue
' [in] strQueueName : Name of queue we want to open
' [in] qaAccessMode : Mode of access (read/write)
' [in] boolPromotUser : prompt the user if we need more information?
' [out] objQueueInfo : Queue info (may be of some use to the caller)
' [retval] : Queue object
'
' This is a general function who's purpose is to open a message queue
' for the user, regarless of wheather or not we (or the queue) are currently
' connectected to the network. This function must be called at least once
' with us connected to the network or it will fail. (The first time we call
' this function on a machine/user we will note the message queues GUID & record
' it for future reference)
'
' [11/10/97, IvoSa] Created
'--------------------------------------------------
Public Function openMessageQueue(ByVal strQueueName As String, ByVal qaAccessMode As MQACCESS, Optional ByVal boolPromotUser As Boolean = True, Optional objQueueInfo As MSMQQueueInfo) As MSMQQueue
Dim strQueueGUID As String
'-------------------------------------------------------------------
'Determine the GUID of the message queue
'-------------------------------------------------------------------
'Get the GUID that uniquely identifies our queue
strQueueGUID = GetSetting(regAPPLICATION_NAME, strQueueName, regKEY_NAME, regNOT_FOUND)
'Was there no value specified for our QUEUE?
If (strQueueGUID = regNOT_FOUND) Then
'See if we can ask the user
If (boolPromotUser = True) Then
Dim lngYesNo As VbMsgBoxResult
lngYesNo = MsgBox("There is no locally registered queue for '" & strQueueName & ". Would you like to look for this queue on the network ('No' will abort)?", vbYesNo)
'If they said no, abort
If (lngYesNo = vbNo) Then
Err.Raise qeNO_QUEUE, "OpenMessageQueue", "There is no registered queue for this user/machine for " & strQueueName
End If
End If
strQueueGUID = LookupGUIDAndPersistToRegisty(strQueueName)
End If
'-------------------------------------------------------------------
'Attempt to open the message queue...
'-------------------------------------------------------------------
Dim lngError As Long
Dim strError As Long
On Error Resume Next
Set objQueueInfo = getQueueInfoForLogon(strQueueGUID)
Set openMessageQueue = objQueueInfo.Open(qaAccessMode, MQ_DENY_NONE)
lngError = Err.Number
strError = Err.Description
On Error GoTo 0
'-------------------------------------------------
'Deal with any errors that may have occured...
'-------------------------------------------------
Select Case lngError
Case 0 'No error
Exit Function 'We are all set
Case MQ_ERROR_QUEUE_NOT_FOUND 'Queue was misregistered (or more likely destroyed & recreated)
'See if we can ask the user
If (boolPromotUser = True) Then
lngYesNo = MsgBox("The local information for '" & strQueueName & " is incorrect. Would you like to look for this queue on the network ('No' will abort)?", vbYesNo)
'If they said no, abort
If (lngYesNo = vbNo) Then
Err.Raise qeNO_QUEUE, "OpenMessageQueue", "There is no registered queue for this user/machine for " & strQueueName
End If
End If
'--------------------------------------------------
'Attempt to open the queue
'--------------------------------------------------
'If an error occurs again then we should justlet it bubble up
strQueueGUID = LookupGUIDAndPersistToRegisty(strQueueName)
Set objQueueInfo = getQueueInfoForLogon(strQueueGUID)
Set openMessageQueue = objQueueInfo.Open(qaAccessMode, MQ_DENY_NONE)
Case Else 'Not an error we're trapping, bubble it up.
Err.Raise lngError, , strError
End Select
End Function
'--------------------------------------------------
'Create message queue
' [in] strQueueName : Name of queue we want to open
' [in] strQueueLocation : Location of our queue ('MACHINENAME\PATH')
' [in] boolPromptUser : Prompt the user for direction if we have problems creating the queue
' [in] boolWorldReadable: Should we make the queue readable by everyone or only by the person who created it...
'
' [retval] T/F : was a 'new' queue created
'
' This is a general function who's purpose is to create a new message queue
'
' [11/10/97, IvoSa] Created
' [12/6/97, IvoSa] Made queue 'World readable'
'--------------------------------------------------
Public Function createMessageQueue(ByVal strQueueName As String, ByVal strQueueLocation As String, Optional ByVal boolPromptUser As Boolean = True, Optional ByVal boolWorldReadable As Boolean = True) As Boolean
Dim objQInfo As MSMQQueueInfo
Dim boolNewQueueCreated As Boolean
boolNewQueueCreated = True 'assume true
'UNDONE: Should add code to check if a Queue of this name already exists.
'Attempt to create the queue
Dim lngError As Long
Dim strError As Long
On Error Resume Next
getQueueInfoForCreation(strQueueLocation, strQueueName).Create
lngError = Err.Number
strError = Err.Description
On Error GoTo 0
Dim lngYesNo As Long
'-------------------------------------------------
'Deal with any errors that may have occured...
'-------------------------------------------------
Select Case lngError
Case 0 'No error
GoTo exit_function '[11/19,97, IvoSa] We are all set
Case MQ_ERROR_QUEUE_EXISTS 'Queue was misregistered (or more likely destroyed & recreated)
'See if we can ask the user
If (boolPromptUser = True) Then
lngYesNo = MsgBox("The queue '" & strQueueName & "' exists. Do you want to delete this and create a new queue? ", vbYesNo)
'If they said no, abort
If (lngYesNo = vbNo) Then
'We have qa queue, they are satisfied, exit.
boolNewQueueCreated = False
GoTo exit_function
End If
Else
'To be on the safe side, we must raise an error
Err.Raise MQ_ERROR_QUEUE_EXISTS, "CreateMessageQueue", "The queue exists '" & strQueueName & "'"
End If
'--------------------------------------------------
'Attempt to delete the queue
'--------------------------------------------------
getQueueInfoForDeletion(strQueueName).Delete
'--------------------------------------------------
'Attempt to create a new queue
'--------------------------------------------------
getQueueInfoForCreation(strQueueLocation, strQueueName).Create IsWorldReadable:=boolWorldReadable '[12/6/97, IvoSa] Public queue access...
'If an error occurs again then we should justlet it bubble up
Case Else 'Not an error we're trapping, bubble it up.
Err.Raise lngError, , strError
End Select
exit_function:
createMessageQueue = boolNewQueueCreated
End Function
'--------------------------------------------------
'Delets a message queue
' [in] strQueueName : Name of queue we want to open
' [in] boolPromotUser : prompt the user if we need more information?
'
' This is a general function who's purpose is to delete a message queue
' for the user.
'
' [11/12/97, IvoSa] Created
'--------------------------------------------------
Public Sub deleteMessageQueue(ByVal strQueueName As String, Optional ByVal boolPromotUser As Boolean = True)
Dim strQueueGUID As String
'-------------------------------------------------------------------
'Determine the GUID of the message queue
'-------------------------------------------------------------------
'Get the GUID that uniquely identifies our queue
strQueueGUID = GetSetting(regAPPLICATION_NAME, strQueueName, regKEY_NAME, regNOT_FOUND)
'Was there no value specified for our QUEUE?
If (strQueueGUID = regNOT_FOUND) Then
'See if we can ask the user
If (boolPromotUser = True) Then
Dim lngYesNo As VbMsgBoxResult
lngYesNo = MsgBox("There is no locally registered queue for '" & strQueueName & ". Would you like to look for this queue on the network ('No' will abort)?", vbYesNo)
'If they said no, abort
If (lngYesNo = vbNo) Then
Err.Raise qeNO_QUEUE, "deleteMessageQueue", "There is no registered queue for this user/machine for " & strQueueName
End If
End If
strQueueGUID = LookupGUIDAndPersistToRegisty(strQueueName)
End If
'-------------------------------------------------------------------
'Attempt to delete the message queue...
'-------------------------------------------------------------------
getQueueInfoForLogon(strQueueGUID).Delete
End Sub
'--------------------------------------------------
'Returns the lablels of all the messages in the queue
' [in] objQueue : Message Queue
'
' [11/10/97, IvoSa] Created
'--------------------------------------------------
Public Function getLabelsOfMessagesInQueue(ByVal objQueue As MSMQQueue) As Collection
Dim objMessage As MSMQMessage
Dim colLables As Collection
'Collection to store the labels in
Set colLables = New Collection
'Go to the first item in the queue
objQueue.Reset
'Itterate through all of the items and add the labels to the collection
Set objMessage = objQueue.PeekCurrent(, , ONE_SECOND) 'ONE_SECOND needed (default delay is infinite)
While Not (objMessage Is Nothing)
colLables.Add objMessage.Label
Set objMessage = objQueue.PeekNext(, , ONE_SECOND) 'ONE_SECOND needed (default delay is infinite)
Wend
'Return the collection of message lablels
Set getLabelsOfMessagesInQueue = colLables
End Function
'-----------------------------------------------------
'Given as message label, retieve the message
' [in] objQueue : Message Queue
' [in] strLabel : Label we want
'
' [11/10/97, IvoSa] Created
'-----------------------------------------------------
Public Function getMessageGivenLabelAndQueue(ByVal objQueue As MSMQQueue, ByVal strLabel As String) As MSMQMessage
Dim objMessage As MSMQMessage
objQueue.Reset 'Go to the first item
'Itterate through all of the items and add the labels to the collection
Set objMessage = objQueue.PeekCurrent(, , ONE_SECOND) 'ONE_SECOND needed (default delay is infinite)
While Not (objMessage Is Nothing)
If objMessage.Label = strLabel Then GoTo found_label
Set objMessage = objQueue.PeekNext(, , ONE_SECOND) 'ONE_SECOND needed (default delay is infinite)
Wend
Set getMessageGivenLabelAndQueue = Nothing
Exit Function
found_label:
Set getMessageGivenLabelAndQueue = objQueue.ReceiveCurrent(receivetimeout:=FIVE_SECONDS)
End Function
'-----------------------------------------------------------
'Sends a message to a queue
' [in] objQueue
' [in] strMessageLabel
' [in] strMessage
' [in] mdMode:
' MQMSG_DELIVERY_RECOVERABLE = Persist it to disk (survives reboot)
' MQMSG_DELIVERY_EXPRESS = Keep it in memory (does not survive reboot)
' [11/12/97, IvoSa] Created
'-----------------------------------------------------------
Sub sendMessageToQueue(ByVal objQueue As MSMQQueue, strMessageLabel As String, strMessage As String, Optional ByVal mdMode As MQMSGDELIVERY = MQMSG_DELIVERY_RECOVERABLE)
Dim objMsg As MSMQMessage
Set objMsg = New MSMQMessage
objMsg.Label = strMessageLabel
objMsg.Body = strMessage
objMsg.Delivery = mdMode
objMsg.Send objQueue
End Sub
'-----------------------------------------------------------
'Get a the labels of all of the messages in the queue & set an event to wait for new messages
' [in] objQueue : message queue
' [out] colMsgLabels : Labels of messages in queue
' [11/13/97, IvoSa] Created
'-----------------------------------------------------------
Public Function getEventFireOnNextMessageArrival(ByVal objQueue As MSMQQueue, Optional colMsgLabels As Collection) As MSMQEvent
'-------------------------------------------------
'Get the labels of all the existing messages & advance to cursor to the end of the queue
'-------------------------------------------------
Set colMsgLabels = getLabelsOfMessagesInQueue(objQueue)
Dim objQEvent As MSMQEvent
Set objQEvent = New MSMQEvent
objQueue.EnableNotification objQEvent, MQMSG_CURRENT
Set getEventFireOnNextMessageArrival = objQEvent
End Function