1.前言
应用程序创建的Queue根据你是否希望被其他程序找到可分为Public Queue和Private Queue,Public Queue会在directory service中注册,有利于长时间的使用。Private Queue在本机注册,而不在directory service中注册,它一般通过在%windir%\System32\MSMQ\Storage\Lqs下存储相应的描叙文件来注册。注册在本机中的Public Queue也会在Lqs目录下存储相应的描述文件。建立Private Queue更快,能在directory service不工作的时候正常工作。
另外按照可以接收的Message类型可分为Transactional Queue和Nontransactional Queue,这个以后再详述。
2.创建Public Nontransactional Queue
HRESULT CreatePublicNontranMSMQQueue(
LPWSTR wszPathName,
LPWSTR wszOutFormatName,
DWORD *pdwOutFormatNameLength
)
{
// Validate the input parameters.
if (wszPathName == NULL || wszOutFormatName == NULL || pdwOutFormatNameLength == NULL)
{
return MQ_ERROR_INVALID_PARAMETER;
}
// Define the maximum number of queue properties.
const int NUMBEROFPROPERTIES = 11;
// Define a queue property structure and the structures needed to initialize it.
MQQUEUEPROPS QueueProps;
MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
HRESULT aQueueStatus[NUMBEROFPROPERTIES];
HRESULT hr = MQ_OK;
// Set queue path.
DWORD cPropId = 0;
aQueuePropId[cPropId] = PROPID_Q_PATHNAME;
aQueuePropVar[cPropId].vt = VT_LPWSTR;
aQueuePropVar[cPropId].pwszVal = wszPathName;
cPropId++;
// Set queue label.
WCHAR wszLabel[MQ_MAX_Q_LABEL_LEN] = L"public non tran";
aQueuePropId[cPropId] = PROPID_Q_LABEL;
aQueuePropVar[cPropId].vt = VT_LPWSTR;
aQueuePropVar[cPropId].pwszVal = wszLabel;
cPropId++;
// Set queue authenticate.
aQueuePropId[cPropId] = PROPID_Q_AUTHENTICATE;
aQueuePropVar[cPropId].vt = VT_UI1;
aQueuePropVar[cPropId].bVal = //MQ_AUTHENTICATE_NONE;//The default. The queue accepts authenticated and non-authenticated messages.
MQ_AUTHENTICATE; //The queue only accepts authenticated messages.
cPropId++;
// Set queue base priority. Applies only to public queues.
aQueuePropId[cPropId] = PROPID_Q_BASEPRIORITY;
aQueuePropVar[cPropId].vt = VT_I2;
aQueuePropVar[cPropId].iVal = 1; //default is 0
cPropId++;
// Set queue privacy level.
aQueuePropId[cPropId] = PROPID_Q_PRIV_LEVEL;
aQueuePropVar[cPropId].vt = VT_UI4;
aQueuePropVar[cPropId].ulVal = //MQ_PRIV_LEVEL_NONE;//The queue accepts only non-private (clear) messages.
MQ_PRIV_LEVEL_BODY;//The queue accepts only private (encrypted) messages.
//MQ_PRIV_LEVEL_OPTIONAL;//The default. The queue does not enforce privacy. It accepts private (encrypted) messages and non-private (clear) messages.
cPropId++;
// Set queue journal.
aQueuePropId[cPropId] = PROPID_Q_JOURNAL;
aQueuePropVar[cPropId].vt = VT_UI1;
aQueuePropVar[cPropId].bVal = MQ_JOURNAL;
//MQ_JOURNAL_NONE;
cPropId++;
// Set queue storage size in KB.
aQueuePropId[cPropId] = PROPID_Q_QUOTA;
aQueuePropVar[cPropId].vt = VT_UI4;
aQueuePropVar[cPropId].ulVal = 1000;
cPropId++;
// Set queue journal storage size in KB.
aQueuePropId[cPropId] = PROPID_Q_JOURNAL_QUOTA;
aQueuePropVar[cPropId].vt = VT_UI4;
aQueuePropVar[cPropId].ulVal = 1000;
cPropId++;
//set broadcast address, not set for transactional queues.
WCHAR AddressBuffer[]=L"224.0.0.255:80";
aQueuePropId[cPropId] = PROPID_Q_MULTICAST_ADDRESS;
aQueuePropVar[cPropId].vt = VT_LPWSTR; //VT_EMPTY if not set.
aQueuePropVar[cPropId].pwszVal = AddressBuffer;
cPropId++;
// set if the queue is transactional queue
aQueuePropId[cPropId] = PROPID_Q_TRANSACTION;
aQueuePropVar[cPropId].vt = VT_UI1;
aQueuePropVar[cPropId].bVal = //MQ_TRANSACTIONAL;
MQ_TRANSACTIONAL_NONE;
cPropId++;
aQueuePropId[cPropId] = PROPID_Q_TYPE;
aQueuePropVar[cPropId].vt = VT_CLSID;
aQueuePropVar[cPropId].puuid = (CLSID*)(&GUID_NULL);
cPropId++;
// Initialize the MQQUEUEPROPS structure.
QueueProps.cProp = cPropId; // Number of properties
QueueProps.aPropID = aQueuePropId; // IDs of the queue properties
QueueProps.aPropVar = aQueuePropVar; // Values of the queue properties
QueueProps.aStatus = aQueueStatus; // Pointer to the return status
// Call MQCreateQueue to create the queue.
WCHAR wszFormatNameBuffer[BUFLEN];
DWORD dwFormatNameBufferLength = BUFLEN;
hr = MQCreateQueue(NULL, // Security descriptor
&QueueProps, // Address of queue property structure
wszOutFormatName, // Pointer to format name buffer
pdwOutFormatNameLength); // Pointer to receive the queue's format name length in Unicode characters not bytes.
return hr;
}
wchar_t formattedQueueName[256];
QUEUEHANDLE m_hQueue;
CreatePublicNontranMSMQQueue(_T(".\\pubnontran"),formattedQueueName,&bufferLength);
3.创建Public transactional Queue
创建Public transactional Queue与Public non-transactional Queue相比,需要把PROPID_Q_TRANSACTION属性设置为MQ_TRANSACTIONAL,且不应设置PROPID_Q_MULTICAST_ADDRESS
//set broadcast address, not set for transactional queues.
aQueuePropId[cPropId] = PROPID_Q_MULTICAST_ADDRESS;
aQueuePropVar[cPropId].vt = VT_EMPTY;
cPropId++;
// set if the queue is transactional queue
aQueuePropId[cPropId] = PROPID_Q_TRANSACTION;
aQueuePropVar[cPropId].vt = VT_UI1;
aQueuePropVar[cPropId].bVal = MQ_TRANSACTIONAL;
//MQ_TRANSACTIONAL_NONE;
cPropId++;
4.创建Private Non-transactional Queue
创建Private Non-transactional Queue与Public Non-transactional Queue相比一个是对PROPID_Q_BASEPRIORITY属性的设置将无效。另一个就是pathname里面需要加private$符号来标明这是个private的Queue。
wchar_t formattedQueueName[256];
QUEUEHANDLE m_hQueue;
CreatePrivateNontranMSMQQueue(_T(".\\private\\prinontran"),formattedQueueName,&bufferLength);