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.
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.
hr = MQGetMachineProperties(
NULL,
NULL,
&QMProps
);
if (FAILED(hr))
WCHAR wszMachineGuid[40];
TBYTE* pszUuid = 0;
if(UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
{
// Handle failure
}
else
{
wcscpy( wszMachineGuid, pszUuid );
RpcStringFree(&pszUuid);
}
wsprintf( wszFormatNameBuffer,
L"MACHINE=%s%s",
wszMachineGuid,
L";DEADLETTER"
);
QUEUEHANDLE hQueue;
hr = MQOpenQueue(
wszFormatNameBuffer,
MQ_RECEIVE_ACCESS,
0,
&hQueue
);
if (FAILED(hr))
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.
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))
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
//
}