Reading Messages in a Dead Letter Queue

Reading messages in a dead letter queue is typically a three-function operation: a call to MQGetMachineProperties to retrieve the local computer identifier (its machine GUID), a call to MQOpenQueue to open the queue with receive access, and a call to MQReceiveMessage to read the message.

To read a message in a dead letter queue
  1. Define an MQQMProps structure that includes PROPID_QM_MACHINE_ID.
    MQQMPROPS QMProps;
    MQPROPVARIANT Variant;
    MSGPROPID PropId;
    GUID    guidMachineId;
        
    PropId = PROPID_QM_MACHINE_ID;                 //PropId
    Variant.vt = VT_CLSID;                         //Type
    Variant.puuid = &guidMachineId;                //Value
        
    QMProps.cProp = 1;                //Number of properties.
    QMProps.aPropID = &PropId;        //Id of property.
    QMProps.aPropVar = &Variant;      //Value of property.
    QMProps.aStatus  = NULL;          //No Error report.
     
  2. Call MQGetMachineProperties to retrieve the machine identifier (PROPID_QM_MACHINE_ID) of the local computer.
    hr = MQGetMachineProperties(
            NULL,
            NULL,
            &QMProps	
            );
    if (FAILED(hr))
     
  3. Translate the machine GUID into a string.
    WCHAR wszMachineGuid[40];
    TBYTE* pszUuid = 0;
    if(UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
    {
      //  Handle failure
    }
    else
    {
        wcscpy( wszMachineGuid, pszUuid );
        RpcStringFree(&pszUuid);
    }
     
  4. Prepare the format name of the dead letter queue.
    wsprintf( wszFormatNameBuffer,
              L"MACHINE=%s%s",
              wszMachineGuid,
              L";DEADLETTER"
              );
     
  5. Call MQOpenQueue and open the queue with receive access.
    QUEUEHANDLE hQueue;
        
    hr = MQOpenQueue(
        wszFormatNameBuffer,
        MQ_RECEIVE_ACCESS,
        0,
        &hQueue
        );
    if (FAILED(hr))
     
  6. Define an MQMSGProps structure for the message properties to be retrieved.
    MQMSGPROPS MsgProps;
    MQPROPVARIANT aVariant[10];
    MSGPROPID aPropId[10];
    DWORD PropIdCount = 0;
        
    // Prepare property array (PROPVARIANT).
    #define MSG_BODY_LEN	500
    unsigned char ucMsgBody[MSG_BODY_LEN];
    DWORD dwAppspecificIndex;
        
    // Set the PROPID_M_BODY property.
    aPropId[PropIdCount] = PROPID_M_BODY;                 //PropId
    aVariant[PropIdCount].vt = VT_VECTOR|VT_UI1;          //Type
    aVariant[PropIdCount].caub.cElems = MSG_BODY_LEN;     //Value
    aVariant[PropIdCount].caub.pElems = ucMsgBody;
       
    PropIdCount++;
        
    // Set the MQMSGPROPS structure
    MsgProps.cProp = PropIdCount;       //Number of properties.
    MsgProps.aPropID = aPropId;         //Ids of properties.
    MsgProps.aPropVar = aVariant;       //Values of properties.
    MsgProps.aStatus  = NULL;           //No Error report.
     
     
  7. Call MQReceiveMessage and retrieve the messages in the queue. The following call retrieves the first message in the queue.
    hr = MQReceiveMessage(
         hQueue,               // handle to the Queue.
         5 * 60 * 1000,        // Max time (msec) to wait for message.
         MQ_ACTION_RECEIVE,    // Action.
         &MsgProps,            // properties to retrieve.
        NULL,                  // No overlapped structure.
        NULL,                  // No callback function.
        NULL,                  // NO cursor.
        NULL                   // No transaction
        );
    if (FAILED(hr))
     

Example

The following example opens a dead letter queue and retrieves the message body of the first message in the queue.

    HRESULT hr;
    #define FORMAT_NAME_LEN 80
    WCHAR wszFormatNameBuffer[ FORMAT_NAME_LEN];
     
    //////////////////////////////////
    //  Define an MQQMPROPS structure 
    //  for PROPID_QM_MACHINE_ID.
    //////////////////////////////////
    
    MQQMPROPS QMProps;
    MQPROPVARIANT Variant;
    MSGPROPID PropId;
    GUID    guidMachineId;
    
    // Set the PROPID_QM_MACHINE_ID property.
    PropId = PROPID_QM_MACHINE_ID;                 //PropId
    Variant.vt = VT_CLSID;                         //Type
    Variant.puuid = &guidMachineId;                //Value
    
    // Set the MQQMPROPS structure
    QMProps.cProp = 1;                //Number of properties.
    QMProps.aPropID = &PropId;        //Id of properties.
    QMProps.aPropVar = &Variant;      //Value of properties.
    QMProps.aStatus  = NULL;          //No Error report.
    
    
    /////////////////////////////////////
    //  Retrieving the identifier of the 
    //  local computer (machine GUID).
    //////////////////////////////////////
    hr = MQGetMachineProperties(
           NULL,
           NULL,
           &QMProps 
           );
    if (FAILED(hr))
    {
        //
        //  Handle failure
        //
    }
    
    
    ///////////////////////////////////
    //  Translating the machine GUID
    //  into a string
    //////////////////////////////////
    WCHAR wszMachineGuid[40];
    WBYTE* pszUuid = 0;
    if(UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
    {
        //
        //  Handle failure
        //
    }
    else
    {
        wcscpy( wszMachineGuid, pszUuid );
        RpcStringFree(&pszUuid);
    }
    
    
    ////////////////////////////////
    //  Preparing the format name of
    //  the dead letter queue.
    ///////////////////////////////
    wsprintf( wszFormatNameBuffer,
              L"MACHINE=%s%s",
              wszMachineGuid,
              L";DEADLETTER"
              );
    
    
    //////////////////////////////
    //  Open the queue for receive
    //////////////////////////////
    
    QUEUEHANDLE hQueue;
    
    hr = MQOpenQueue(
        wszFormatNameBuffer,
        MQ_RECEIVE_ACCESS,
        0,
        &hQueue
        );
    if (FAILED(hr))
    {
        //
        //  Handle failure
        //
    }
 
    //////////////////////////////////
    //  Define an MQMSGPROPS structure 
    //  for the message properties to 
    //  be retrieved.
    //////////////////////////////////
    
    MQMSGPROPS MsgProps;
    MQPROPVARIANT aVariant[10];
    MSGPROPID aPropId[10];
    DWORD PropIdCount = 0;
    
    // Prepare property array (PROPVARIANT).
    #define MSG_BODY_LEN	500
    unsigned char ucMsgBody[MSG_BODY_LEN];
    DWORD dwAppspecificIndex;
    
    // Set the PROPID_M_BODY property.
    aPropId[PropIdCount] = PROPID_M_BODY;                 //PropId
    aVariant[PropIdCount].vt = VT_VECTOR|VT_UI1;          //Type
    aVariant[PropIdCount].caub.cElems = MSG_BODY_LEN;     //Value
    aVariant[PropIdCount].caub.pElems = ucMsgBody;
    
    PropIdCount++;
    
    // Set the MQMSGPROPS structure
    MsgProps.cProp = PropIdCount;       //Number of properties.
    MsgProps.aPropID = aPropId;         //Ids of properties.
    MsgProps.aPropVar = aVariant;       //Values of properties.
    MsgProps.aStatus  = NULL;           //No Error report.
 
 
    /////////////////////////////////////
    // Read first message in dead 
    // letter queue.
    /////////////////////////////////////
 
    hr = MQReceiveMessage(
         hQueue,               // handle to the Queue.
         5 * 60 * 1000,        // Max time (msec) to wait for message.
         MQ_ACTION_RECEIVE,    // Action.
         &MsgProps,            // properties to retrieve.
        NULL,                  // No overlapped structure.
        NULL,                  // No callback function.
        NULL,                  // NO cursor.
        NULL                   // No transaction
        );
    if (FAILED(hr))
    {
    //
    //  Handle failure
    //
    }
 

© 1997 by Microsoft Corporation. All rights reserved.