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条。

posted @   Jingle Guo  阅读(564)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示