Пример #1
1
bool CMsmqWarpper::OpenPublicQueue(LPCWSTR wszPathName, bool connecttype)
{
	if (wszPathName == NULL)
	{
		return false;
	}

	HRESULT hr = MQ_OK;

	if (connecttype)
	{
		DWORD dwFormatNameBufferLength = 256; 
		WCHAR wszFormatNameBuffer[256] = {0};

		hr = MQPathNameToFormatName(wszPathName,
			wszFormatNameBuffer,
			&dwFormatNameBufferLength);
		if (FAILED(hr))
		{
			return false;
		}

		hr = MQOpenQueue(wszFormatNameBuffer, 
			MQ_SEND_ACCESS, 
			MQ_DENY_NONE, 
			&m_hQueue
			);
	}
	else
	{
		hr = MQOpenQueue(wszPathName, 
			MQ_SEND_ACCESS, 
			MQ_DENY_NONE, 
			&m_hQueue
			);
	}
	if (FAILED(hr))
	{
		return false;
	}

	return true;

}
//--------------------------------------------------------
//
// Receiver Mode
// -------------
// The receiver side does the following:
//    1. Creates a queue on the local computer
//       of type "guidMQTestType".
//       The queue is either public or private, depending
//       on the connection we want to establish.
//    2. Opens the queue.
//    3. In a loop,
//          receives messages
//          and prints the message body and message label.
//    4. Cleans up handles.
//    5. Deletes the queue from the directory service.
//
//--------------------------------------------------------
void Receiver(int dDirectMode)
{

    MQQUEUEPROPS  qprops;
    MQMSGPROPS    msgprops;
    MQPROPVARIANT aPropVar[MAX_VAR];
    QUEUEPROPID   aqPropId[MAX_VAR];
    MSGPROPID     amPropId[MAX_VAR];
    DWORD         cProps;

    WCHAR         wcsFormat[MAX_FORMAT];

    UCHAR         Buffer[MAX_BUFFER];
    WCHAR         wcsMsgLabel[MQ_MAX_MSG_LABEL_LEN+1];
    WCHAR         wcsPathName[MAX_FORMAT];


    DWORD         dwNumChars;
    QUEUEHANDLE   qh;

    HRESULT       hr;
	int			  nPos;

    printf("\nReceiver Mode on Machine: %s\n\n", mbsMachineName);


    //
    // Set properties to create a queue on the local computer.
    //
    cProps = 0;

    // Set the path name.
    if(dDirectMode == DIRECT)  // Private queue path name
    {
		nPos = _snwprintf_s(
                           wcsPathName, 
                           sizeof(wcsPathName)/sizeof(wcsPathName[0]), 
                           sizeof(wcsPathName)/sizeof(wcsPathName[0]) - 1, 
                           L"%S\\private$\\MSMQTest", 
                           mbsMachineName
                           );
		if(nPos < 0)
		{
			printf("The path name is too long for the buffer. Exiting...\n");
			exit(1);
		}	

    }
    else                       // Public queue path name
    {    
		nPos = _snwprintf_s(
                           wcsPathName, 
                           sizeof(wcsPathName)/sizeof(wcsPathName[0]), 
                           sizeof(wcsPathName)/sizeof(wcsPathName[0]) - 1, 
                           L"%S\\MSMQTest", 
                           mbsMachineName
                           );
		if(nPos < 0)
		{
			printf("The path name is too long for the buffer. Exiting...\n");
			exit(1);
		}	

    }

    aqPropId[cProps]         = PROPID_Q_PATHNAME;
    aPropVar[cProps].vt      = VT_LPWSTR;
    aPropVar[cProps].pwszVal = wcsPathName;
    cProps++;

    // Specify the service type GUID of the queue.
    // (This property will be used to locate all the queues of this type.)
    aqPropId[cProps]         = PROPID_Q_TYPE;
    aPropVar[cProps].vt      = VT_CLSID;
    aPropVar[cProps].puuid   = &guidMQTestType;
    cProps++;

    // Add a descriptive label to the queue.
    // (A label is useful for administration through the MSMQ admin tools.)
    aqPropId[cProps]         = PROPID_Q_LABEL;
    aPropVar[cProps].vt      = VT_LPWSTR;
    aPropVar[cProps].pwszVal = L"Sample application of MSMQ SDK";
    cProps++;

    // Create a QUEUEPROPS structure.
    qprops.cProp    = cProps;
    qprops.aPropID  = aqPropId;
    qprops.aPropVar = aPropVar;
    qprops.aStatus  = 0;


    //
    // Create the queue.
    //
    dwNumChars = MAX_FORMAT;
    hr = MQCreateQueue(
            NULL,           // IN:     Default security
            &qprops,        // IN/OUT: Queue properties
            wcsFormat,      // OUT:    Format name
            &dwNumChars);   // IN/OUT: Size of the format name

    if (FAILED(hr))
    {
        //
        // API failed, but not because the queue exists.
        //
        if (hr != MQ_ERROR_QUEUE_EXISTS)
            Error("MQCreateQueue failed", hr);

        //
        // The queue exist, so get its format name.
        //
        printf("The queue already exists. Open it anyway.\n");

        if(dDirectMode == DIRECT)
        // It's a private queue, so we know its direct format name.
        {
			int n = _snwprintf_s(
                                    wcsFormat, 
                                    sizeof(wcsFormat)/sizeof(wcsFormat[0]), 
                                    sizeof(wcsFormat)/sizeof(wcsFormat[0]) - 1, 
                                    L"DIRECT=OS:%s", 
                                    wcsPathName);
			if(n < 0)
			{
				printf("The format name is too long for the buffer. Exiting...\n");
				exit(1);
			}	

        }
        else
        // It's a public queue, so we must get its format name from the DS.
        {
            dwNumChars = sizeof(wcsFormat)/sizeof(wcsFormat[0]);
            hr = MQPathNameToFormatName(
                       wcsPathName,     // IN:     Queue path name
                       wcsFormat,       // OUT:    Format name
                       &dwNumChars);    // IN/OUT: Size of the format name

            if (FAILED(hr))
                Error("The format name cannot be retrieved", hr);
        }
    }


    //
    // Open the queue with receive access.
    //
    hr = MQOpenQueue(
             wcsFormat,          // IN:  Queue format name
             MQ_RECEIVE_ACCESS,  // IN:  Want to receive from queue
             0,                  // IN:  Allow sharing
             &qh);               // OUT: Handle of open queue

    //
    // Things are a little bit tricky. MQCreateQueue succeeded, but in the 
    // case of a public queue, this does not mean that MQOpenQueue
    // will succeed, because replication delays are possible. The queue is
    // registered in the DS, but it might take a replication interval
    // until the replica reaches the server that I am connected to.
    // To overcome this, open the queue in a loop.
    //
    // In this specific case, this can happen only if this program
    // is run on an MSMQ 1.0 backup server controller (BSC) or on
    // a client connected to a BSC.
    // To be totally on the safe side, we should have put some code
    // to exit the loop after a few retries, but this is just a sample.
    //
    while (hr == MQ_ERROR_QUEUE_NOT_FOUND)
    {
       printf(".");

       // Wait a bit.
       Sleep(500);

       // Retry.
       hr = MQOpenQueue(wcsFormat, MQ_RECEIVE_ACCESS, 0, &qh);
    }

    if (FAILED(hr))
         Error("The queue cannot be opened", hr);


    //
    // Main receiver loop
    //
    if(dDirectMode == DIRECT)
    {
        printf("\n* Working in workgroup (direct) mode.\n");
    }
    printf("\n* Waiting for messages...\n");
    
    for(;;)
    {
        //
        // Set the message properties for reading messages.
        //
        cProps = 0;

        // Ask for the body of the message.
        amPropId[cProps]            = PROPID_M_BODY;
        aPropVar[cProps].vt         = VT_UI1 | VT_VECTOR;
        aPropVar[cProps].caub.cElems = sizeof(Buffer);
        aPropVar[cProps].caub.pElems = Buffer;
        cProps++;

        // Ask for the label of the message.
        amPropId[cProps]         = PROPID_M_LABEL;
        aPropVar[cProps].vt      = VT_LPWSTR;
        aPropVar[cProps].pwszVal = wcsMsgLabel;
        cProps++;

        // Ask for the length of the label of the message.
        amPropId[cProps]         = PROPID_M_LABEL_LEN;
        aPropVar[cProps].vt      = VT_UI4;
        aPropVar[cProps].ulVal   = sizeof(wcsMsgLabel);
        cProps++;

        // Create a MSGPROPS structure.
        msgprops.cProp    = cProps;
        msgprops.aPropID  = amPropId;
        msgprops.aPropVar = aPropVar;
        msgprops.aStatus  = 0;


        //
        // Receive the message.
        //
        hr = MQReceiveMessage(
               qh,                // IN:     Queue handle
               INFINITE,          // IN:     Time-out
               MQ_ACTION_RECEIVE, // IN:     Read operation
               &msgprops,         // IN/OUT: Message properties to retrieve
               NULL,              // IN/OUT: No OVERLAPPED structure
               NULL,              // IN:     No callback
               NULL,              // IN:     No cursor
               NULL);             // IN:     Not part of a transaction

        if (FAILED(hr))
            Error("MQReceiveMessage failed", hr);

        //
        // Display the received message.
        //
        printf("%S : %s\n", wcsMsgLabel, Buffer);

        //
        // Check for a request to end the application.
        //
        if (_stricmp(Buffer, "quit") == 0)
            break;

    } /* while (1) */

    //
    // Cleanup: Close the handle to the queue.
    //
    MQCloseQueue(qh);


    //
    // In the concluding stage, we delete the queue from the directory
    // service. (We don't need to do this. In case of a public queue, 
    // leaving it in the DS enables sender applications to send messages 
    // even if the receiver is not available.)
    //
    hr = MQDeleteQueue(wcsFormat);
    if (FAILED(hr))
        Error("The queue cannot be deleted", hr);
}
Пример #3
0
BOOL CDisdrawDlg::OpenReceiveQueue()
{
    //
    // Do not create the receiving queue if it already exists in the enterprise.
    //
    HRESULT hr;
	WCHAR wcsFormatName[MAX_FORMAT_NAME_LEN+1];
    if (!LocateQueue(m_strLogin, wcsFormatName, sizeof(wcsFormatName)/sizeof(wcsFormatName[0])))
    {
    	//
    	// Form the pathname of the receiving queue.
    	//
    	char mbsPathName[MQ_MAX_Q_NAME_LEN+1];
    	DWORD dwNumChars = sizeof(mbsPathName);
    	GetComputerName(mbsPathName, &dwNumChars);
	strcat_s(mbsPathName, sizeof(mbsPathName), "\\");
        strcat_s(mbsPathName, sizeof(mbsPathName), m_strLogin);


    	//
    	// Prepare the receiving queue properties.
    	//
    	DWORD cProps = 0;
    	QUEUEPROPID  aPropId[3];
    	MQPROPVARIANT aPropVar[3];
	    MQQUEUEPROPS propsQueue;
	    
		WCHAR wcsPathName[MQ_MAX_Q_NAME_LEN+1];
                size_t nResultedStringLength=0;
		mbstowcs_s(
                    &nResultedStringLength,
                    wcsPathName, 
                    sizeof(wcsPathName)/sizeof(wcsPathName[0]),
                    mbsPathName, 
                    sizeof(wcsPathName)/sizeof(wcsPathName[0])-1
                    );
	    aPropId[cProps]			 = PROPID_Q_PATHNAME;
	    aPropVar[cProps].vt		 = VT_LPWSTR;
	    aPropVar[cProps].pwszVal = wcsPathName;
	    cProps++;

	    aPropId[cProps]			 = PROPID_Q_TYPE;
	    aPropVar[cProps].vt		 = VT_CLSID;
	    aPropVar[cProps].puuid	 = &guidDrawType;
	    cProps++;

		WCHAR wcsLabel[MQ_MAX_Q_LABEL_LEN+1];
                nResultedStringLength=0;
		mbstowcs_s(
                    &nResultedStringLength,
                    wcsLabel, 
                    sizeof(wcsLabel)/sizeof(wcsLabel[0]),
                    m_strLogin, 
                    sizeof(wcsLabel)/sizeof(wcsLabel[0])-1
                    );
	    aPropId[cProps]			 = PROPID_Q_LABEL;
	    aPropVar[cProps].vt		 = VT_LPWSTR;
	    aPropVar[cProps].pwszVal = wcsLabel;
	    cProps++;

	    propsQueue.cProp	= cProps;
	    propsQueue.aPropID	= aPropId;
	    propsQueue.aPropVar = aPropVar;
	    propsQueue.aStatus	= NULL;


	    //
	    // Create the receiving queue.
	    //
	    dwNumChars = sizeof(wcsFormatName)/sizeof(wcsFormatName[0]);
	    hr = MQCreateQueue(NULL, &propsQueue, wcsFormatName, &dwNumChars);	


	    //
	    // If the receiving queue already exists, obtain its format name.
	    //
	    if (hr == MQ_ERROR_QUEUE_EXISTS)
            {
         	    dwNumChars = sizeof(wcsFormatName)/sizeof(wcsFormatName[0]);
		    hr = MQPathNameToFormatName(wcsPathName, wcsFormatName, &dwNumChars);
            }

	    if (FAILED(hr))
		    return FALSE;
    }

	//
	// Open the receiving queue (it may be necessary to retry due to replication latency).
	//
    int iCount = 0;
	while ((hr = MQOpenQueue(wcsFormatName, 
                             MQ_RECEIVE_ACCESS, 
                             MQ_DENY_NONE ,
                             &m_hqIncoming)) == MQ_ERROR_QUEUE_NOT_FOUND)
    {
		
        Sleep (500);
        iCount++;
        if (iCount >=30)
        {
            //
            // A period of 15 seconds past without locating the queue.
            // We allow the user to stop attempts to open the queue.
            //
            int iRes = MessageBox("The receiving queue was not located.\nDo you want to continue searching?",
                                NULL,
                                MB_YESNO);
            if(iRes == IDYES)
            {
                //
                // Continue searching.
                //
                iCount =0;
            }
            else
            {
                //
                // Stop searching.
                //
                break;
            }
        }
    }

	if (FAILED(hr))
		return FALSE;


	return TRUE;
}