Message Queuing(MSMQ)学习之旅(二)——创建Queue
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_EMPTY //not set multicast address. //aQueuePropVar[cPropId].vt = VT_LPWSTR; //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(L".\\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(L".\\private$\\prinontran",formattedQueueName,&bufferLength);
5.创建Private transactional Queue
创建方法参见2,3,4条。
作者:Jingle Guo
出处:http://www.cnblogs.com/studynote/
若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.