MSMQ学习笔记二——创建Message Queue队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MSMQ学习笔记二——创建Message Queue队列相关的知识,希望对你有一定的参考价值。

一、创建Message Queue队列的主要流程

  1、定义MQQUEUEPROPS 结构;

  2、设置消息队列属性;

  3、初始化MQQUEUEPROPS 结构;

  4、调用MQCreateQueue创建队列。

  下面对MSDN上的创建Message Queue队列示例函数:

HRESULT CreateMSMQQueue(
                        LPWSTR wszPathName, 
                        PSECURITY_DESCRIPTOR pSecurityDescriptor,
                        LPWSTR wszOutFormatName,
                        DWORD *pdwOutFormatNameLength
                        )
{
    // Define the maximum number of queue properties.
    const int NUMBEROFPROPERTIES = 2;
    const int BUFLEN = 256;

    // 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;

    // Validate the input parameters.
    if (wszPathName == NULL || wszOutFormatName == NULL || pdwOutFormatNameLength == NULL)
    {
        return MQ_ERROR_INVALID_PARAMETER;
    }

    // Set queue properties.
    DWORD cPropId = 0;
    aQueuePropId[cPropId] = PROPID_Q_PATHNAME;
    aQueuePropVar[cPropId].vt = VT_LPWSTR;
    aQueuePropVar[cPropId].pwszVal = wszPathName;
    cPropId++;

    WCHAR wszLabel[MQ_MAX_Q_LABEL_LEN] = L"Test Queue";
    aQueuePropId[cPropId] = PROPID_Q_LABEL;
    aQueuePropVar[cPropId].vt = VT_LPWSTR;
    aQueuePropVar[cPropId].pwszVal = wszLabel;
    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(pSecurityDescriptor, // Security descriptor
     &QueueProps, // Address of queue property structure
     wszFormatNameBuffer, // Pointer to format name buffer
     &dwFormatNameBufferLength);// Pointer to receive the queue‘s format name length in Unicode characters not bytes.

    // Return the format name if the queue is created successfully.
    if (hr == MQ_OK || hr == MQ_INFORMATION_PROPERTY)
    {
        if (*pdwOutFormatNameLength >= dwFormatNameBufferLength)
        {
            wcsncpy_s(wszOutFormatName, *pdwOutFormatNameLength - 1, wszFormatNameBuffer, _TRUNCATE);
            // ************************************
            // You must copy wszFormatNameBuffer into the 
            // wszOutFormatName buffer.
            // ************************************
            wszOutFormatName[*pdwOutFormatNameLength - 1] = L\\0;
            *pdwOutFormatNameLength = dwFormatNameBufferLength;
        }
        else
        {
            wprintf(L"The queue was created, but its format name cannot be returned.\\n");
        }
    }
    return hr;
}

注意:需要包含头文件windows.h、mq.h、stdio.h和lib库mqrt.lib。

二、示例

  以下为测试示例:

int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t name[]=L".\\\\PRIVATE$\\\\ZHXL.121";
    DWORD bufferLength = 256;
    wchar_t formattedQueueName[256]; 

    HRESULT returnValue = CreateMSMQQueue(name,NULL,formattedQueueName,&bufferLength);

    if(returnValue != MQ_OK)
    wprintf(L"Creating a Queue failed\\n");
    else
    {
     wprintf(L"Queue was successfully created..Formatted QueueName =%s\\n",formattedQueueName);
     wprintf(L"BufferLength returned is %d\\n", bufferLength);
    }

    return 0;
}

  运行结果为:

技术分享

三、补充

  1、MQQUEUEPROPS结构体

  该结构体定义为:

typedef struct tagMQQUEUEPROPS
{
    DWORD           cProp;
    __field_ecount(cProp) QUEUEPROPID*    aPropID;
    __field_ecount(cProp) MQPROPVARIANT*  aPropVar;
    __field_ecount_opt(cProp) HRESULT*        aStatus;
} MQQUEUEPROPS;

  cProp:属性总个数;

  aPropID:属性标识符,Message Queue必需属性的标识符有PROPID_Q_PATHNAME和PROPID_Q_LABEL两个,分别为指定队列的路径和描述性标签;

  aPropVar:消息队列属性的值;

  2、消息队列创建之后一直存在,创建同名消息队列会失败,需要用到指定队列时所需操作为打开制定队列,利用完事后关闭队列。

 

以上是关于MSMQ学习笔记二——创建Message Queue队列的主要内容,如果未能解决你的问题,请参考以下文章

MSMQ(消息队列)

PetShop 4.0学习笔记:消息队列MSMQ

Redis学习笔记~实现消息队列比MSMQ更方便

MSMQ(Microsoft Message Queue)

MSMQ(消息队列)

MSMQ(消息队列)续