C-C++ Code Example: Reading Messages in a Queue Journal

 

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 an application-defined function that synchronously reads all the messages in the journal of a known destination queue, retrieving the PROPID_M_LABEL property and displaying the label of each message in the journal.

For information on when Message Queuing sends messages to the journal of a queue, see Target Journaling.

To read messages in a queue journal

  1. Define an MQMSGPROPS structure.

  2. Specify the message label and its length as the message properties that you want to retrieve.

  3. Initialize the MQMSGPROPS structure.

  4. Construct the format name of the queue journal from the computer name and queue name supplied by the caller. In the case of a private queue, the caller must prefix the queue name with the PRIVATE$ keyword.

  5. Call MQOpenQueue to open the computer journal with receive access.

  6. In a loop, call MQReceiveMessage and synchronously read all the messages in the queue journal.

  7. Call MQCloseQueue to close the queue journal and free resources.

Code Example

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

HRESULT ReadQueueJournal(  
                         LPCWSTR wszComputerName,  
                         LPCWSTR wszQueueName  
                         )  
{  
  
  // Validate the input strings.  
  if (wszComputerName == NULL || wszQueueName == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  // Define the required constants, variables, and structures.  
  const int NUMBEROFPROPERTIES = 2;              // Number of properties  
  DWORD cPropId = 0;                             // Property counter  
  HANDLE hQueue = NULL;                          // Queue handle  
  HRESULT hr = MQ_OK;  
  
  //Define an MQMSGPROPS structure.  
  MQMSGPROPS msgprops;  
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];  
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];  
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];  
  
  // Specify the message label and its length as message properties to be retrieved.  
  WCHAR wszLabelBuffer[MQ_MAX_MSG_LABEL_LEN];         // Message label buffer  
  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID  
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type indicator  
  aMsgPropVar[cPropId].ulVal = MQ_MAX_MSG_LABEL_LEN;  // Label buffer size  
  cPropId++;  
  
  aMsgPropId[cPropId] = PROPID_M_LABEL;               // Property ID  
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type indicator  
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;      // Label buffer  
  cPropId++;  
  
  // Initialize the MQMSGPROPS structure.  
  msgprops.cProp = cPropId;                          // Number of message properties  
  msgprops.aPropID = aMsgPropId;                     // IDs of message properties  
  msgprops.aPropVar = aMsgPropVar;                   // Values of message properties  
  msgprops.aStatus = aMsgStatus;                     // Error reports  
  
  // Create the direct format name of the queue journal.  
  WCHAR * wszFormatName = NULL;  
  DWORD dwFormatNameLength = 0;  
  dwFormatNameLength = wcslen(wszComputerName) + wcslen(wszQueueName) + 20;  
  wszFormatName = new WCHAR[dwFormatNameLength];  
  if (wszFormatName == NULL)  
  {  
    return MQ_ERROR_INSUFFICIENT_RESOURCES;  
  }  
  memset(wszFormatName, 0, dwFormatNameLength);  
  // ************************************  
  // You must concatenate "DIRECT=OS:", wszComputerName , "\",   
  // wszQueueName, and ";JOURNAL" into the wszFormatName buffer.  
  // wszFormatName = "DIRECT=OS:" + wszComputerName + "\" +   
  // wszQueueName + ";JOURNAL"  
  // if the format name is too long for the buffer, return FALSE.  
  // ************************************  
  
  // Open the journal queue to read messages.  
  hr = MQOpenQueue(  
                   wszFormatName,                    // Format name of the computer journal  
                   MQ_RECEIVE_ACCESS,                // Access mode  
                   MQ_DENY_RECEIVE_SHARE,            // Share mode  
                   &hQueue                           // OUT: Queue handle  
                   );  
  
  // Free the memory that was allocated for the format name string.  
  if (wszFormatName)  
  {  
    delete [] wszFormatName;  
  }  
  
  // Handle any error returned by MQOpenQueue.  
  if (FAILED(hr))  
  {  
    return hr;  
  }  
  
  // Read all the messages in the journal queue.  
  for ( ; ; )  
  {  
    hr = MQReceiveMessage(  
                          hQueue,                   // Queue handle  
                          0,                        // Maximum time (msec)  
                          MQ_ACTION_RECEIVE,        // Receive action  
                          &msgprops,                // Message property structure  
                          NULL,                     // No OVERLAPPED structure  
                          NULL,                     // No callback function  
                          NULL,                     // Cursor handle  
                          MQ_NO_TRANSACTION         // No transaction  
                          );  
    if (FAILED(hr))  
    {  
      break;  
    }  
  
    if (msgProps.aPropVar[0].ulVal)                // Label returned  
    {  
      wprintf(L"A message was found in the queue journal. Label: %s\n", aMsgPropVar[1].pwszVal);  
    }  
    else  
    {  
      wprintf(L"A message was found in the queue journal.\n");  
    }  
  }  
  
  // Call MQCloseQueue to close the queue journal.  
  hr = MQCloseQueue(hQueue);  
  
  return hr;  
}