我需要开始编写一些MSMQ代码,它将与其他机器上的WCF代码进行交互.有MSMQ经验的人是否使用直接C与使用COM对MSMQ的优缺点提出建议?

解决方法

其实你不必决定.你可以结合起来.

以下是完整发送/ recv实现的代码示例.

如果你改进它,请告诉我……

h文件:

#pragma once

#include <tchar.h>

// ==========================================================================
// MSMQWrapper - wrappes the COM object used to send and receive messages through the MSMQ
class CMSMQWrapper
{
    HANDLE m_hQ;

public:
    CMSMQWrapper()
    {
        m_hQ= INVALID_HANDLE_VALUE;
        ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
    }

    ~CMSMQWrapper()
    {
        ::CoUninitialize();
    }

    bool InitLocalQueue (const WCHAR* wczQueueName     ); // [i] .\private$\queue_name
    bool InitDestQueue  (const WCHAR* wczDestQueueName ); // [i] comp_name\private$\queue_name

    bool ReadQueue      (const WCHAR* wczQueueName,// [i]
                               BYTE*  pBuf,// [i]
                               size_t nBufLen,// [i]
                               int&   nBytesRead       ); // [o]

    bool SendToDestQueue(const BYTE*  pBuf,size_t nBufLen          );
};

cpp文件:

#include "stdafx.h"
#include "msmqwrap.h"

#include <windows.h>
#include <AtlBase.h>
#import "mqoa.dll" named_guids // no_namespace

#pragma comment (lib,"Mqrt.lib")
#include "mq.h"

using namespace MSMQ;

// ==========================================================================
// CMSMQWrapper
// ==========================================================================

bool CMSMQWrapper::InitLocalQueue(const WCHAR* wczQueueName)
{
    CComQIPtr<imsMQQueueInfo,&IID_imsMQQueueInfo> ipQueueInfo;

    HRESULT hr= ::CoCreateInstance(CLSID_MSMQQueueInfo,NULL,CLSCTX_SERVER,IID_imsMQQueueInfo,(void**)(&ipQueueInfo.p) );
    if (S_OK != hr)
        return false;

    hr= ipQueueInfo->put_PathName(_bstr_t(wczQueueName));
    if (S_OK != hr)
        return false;

    hr= ipQueueInfo->put_Label(_bstr_t(wczQueueName));
    if (S_OK != hr)
        return false;

    VARIANT vtFalse;
    Variantinit(&vtFalse);
    vtFalse.vt     = VT_BOOL;
    vtFalse.boolVal= FALSE  ;

    try
    {
        hr= ipQueueInfo->Create(&vtFalse,&vtFalse);
    }
    catch (_com_error& er)
    { 
        if (MQ_ERROR_QUEUE_EXISTS == er.Error()) // queue already exists
            hr= S_OK;
        else
        {
            // report error - Failed receiving,(WCHAR*)er.Description()
            return false;
        }
    }

    return true;
}

// --------------------------------------------------------------------------
bool CMSMQWrapper::ReadQueue(const WCHAR* wczQueueName,// [i]
                             BYTE*        pBuf,// [i]
                             size_t       nBufLen,// [i]
                             int&         nBytesRead   ) // [o]
{
    // set value of ReceiveTimout parameter
    _variant_t vtReceiveTimeout;
    vtReceiveTimeout= (long)INFINITE;

    try
    {
        imsMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
        qinfo->PathName= wczQueueName;

        imsMQQueuePtr qRec;
        qRec= qinfo->Open(MQ_RECEIVE_ACCESS,MQ_DENY_NONE); // open queue to retrieve message

        // retrieve messages from queue
        imsMQMessagePtr msgRec("MSMQ.MSMQMessage");
        msgRec= qRec->Receive(&vtMissing,&vtMissing,&vtReceiveTimeout);
        if (NULL == msgRec)
        {
            nBytesRead= 0; // there are no messages in the queue
            return true;
        }

        nBytesRead           = msgRec->BodyLength;
        _variant_t recVariant= msgRec->Body      ;

        // close queue
        qRec->Close();

        SAFEARRAY* psa= recVariant.parray;
        nBytesRead    = __min(psa->rgsabound->cElements,nBufLen);

        for (LONG ind= 0; ind< nBytesRead; ind++)
            SafeArrayGetElement(psa,&ind,&pBuf[ind]);

        return true;
    }
    catch (_com_error comerr)
    {
        // report error - Failed receiving,(WCHAR*)comerr.Description());
        return false;
    }
}

// --------------------------------------------------------------------------
bool CMSMQWrapper::InitDestQueue(const WCHAR* wczDestQueueName) // comp_name\private$\queue_name
{
    // validate the input strings
    if (NULL == wczDestQueueName)
        return false;

    // create a direct format name for the queue
    WCHAR wczFormatName[1000];
    str_cat(wczFormatName,1000,L"DIRECT=OS:",wczDestQueueName);

    HRESULT hr;
    hr = ::MQOpenQueue(wczFormatName,MQ_SEND_ACCESS,MQ_DENY_NONE,&m_hQ);
    if (MQ_OK != hr) //MQ_ERROR_QUEUE_NOT_FOUND
        return false;

    return true;
}

// --------------------------------------------------------------------------
bool CMSMQWrapper::SendToDestQueue(const BYTE* pBuf,size_t nBufLen)
{
    MQMSGPROPS  MsgProps         ;
    const UINT  _nProps= 1       ;
    MSGPROPID   aPropId [_nProps];
    PROPVARIANT aVariant[_nProps];

    aPropId [0]            = PROPID_M_BODY   ; // msg to send
    aVariant[0].vt         = VT_VECTOR|VT_UI1;
    aVariant[0].caub.pElems= (BYTE*)pBuf     ;
    aVariant[0].caub.cElems= nBufLen         ;

    MsgProps.cProp         = _nProps         ; // number of props to set
    MsgProps.aPropID       = aPropId         ;
    MsgProps.aPropVar      = aVariant        ;
    MsgProps.aStatus       = 0               ;

    if (MQ_OK != ::MQSendMessage(m_hQ,&MsgProps,MQ_NO_TRANSACTION))
        return false;

    return true;
}

MSMQ – C还是COM?的更多相关文章

  1. windows-7 – MSMQ问题读取远程私人队列(再次)

    我也尝试关闭W7和XP防火墙,并给予每个人和他的狗对队列本身的完全权限无济于事.鉴于它与XP一起作为队列主机,但不与W7作为主机,我认为这是一个安全问题,而不是代码问题.但对于我的生活,我无法看到W7在哪里堵塞.编辑8/9好的..添加允许我从远程专用队列中读取消息.但是这似乎不允许使用枚举可用的私有队列.那么这个想法有什么想法吗?

  2. windows-services – Msmq和WCF服务

    我是否遗漏了为队列和Windows服务设置的任何权限,如果是这样,你能否建议在哪里添加这些权限?汤姆·霍兰德有一个关于使用WCF的MSMQ的三部分博客系列–非常值得一试!

  3. windows-server-2003 – 就MSMQ而言,独立客户端和依赖客户端之间有什么区别

    我有一个客户端有一个服务器,其中有一个.net应用程序试图写入另一台服务器上的MSMQ.他们得到错误“MSMQ独立客户端无法为MSMQ依赖客户端提供服务”.这两者有什么区别,是否有一种简单的方法使服务器A独立?

  4. windows-server-2008 – 通过HTTP的MSMQ – 为什么我们需要TCP端口1801?

    提前致谢.请放心,文档在这一点上是完全错误的.我很尴尬因为我在微软的MSMQ支持工作期间从未发现产品组写的内容.我会看看我是否可以找人修理这些信息.

  5. windows-server-2003 – 如何确定MSMQ 3.0容量和服务器规格?

    我正在尝试确定MSMQ服务器所需的资源,并且在阅读文档时感到困惑.例如,MSMQ3.0可以存储25GB的消息,如果是,那么支持它所需的服务器规范是什么?您可能需要重新检查应用程序是否已正确设计用于加载将要处理的消息.

  6. msmq – 有没有办法只查看计算机管理的消息队列部分?

    我打开电脑管理,扩展服务和应用,然后展开消息队列和私人队列……一些组件可以在外面打开计算机管理,例如:事件查看器通过Start,Run,eventvwr.是否有可能做同样的事情消息队列?thnx~~gerry遵循mark的建议,并在其中保存一个带有计算机管理的新.msc.然后在左侧树视图中打开MSC,扩展私人消息队列或您经常工作的任何部分,当您退出时,它会询问您是否要保存.msc–说是,下次打开它时,它会保存到你保存的地方.

  7. 没有SAN的MSMQ的Windows故障转移群集?

    我们的目标是创建一个没有任何单点故障的集群MSMQ.理想情况下,存储的消息将保留在集群的所有节点上,这样,如果任何单个节点脱机,集群可以继续运行并维护仲裁.或者,是否有另一种更好的方法来创建高可用性MSMQ?

  8. 是否可以在Windows 8上从PowerShell启用MSMQ?

    是否可以在Windows8(.1)上从PowerShell启用MSMQ?

  9. 权限 – 编辑MSMQ Messsage队列属性时拒绝访问

    我正在尝试通过计算机管理在我的计算机上调整消息队列属性.它失败并显示以下消息:无法设置属性.错误:访问被拒绝.我使用属于本地Administrators组的帐户登录.我可以执行我尝试过的所有其他管理任务.什么可能阻止我改变这些设置?

  10. 已收到MSMQ消息但未提供Windows 2008 R2

    我有一个名为myPrivateTransactionQueue的事务性队列,托管在名为myReceivingServer的Win2008R2服务器上,该服务器应该从另一个名为mySendingServer的服务器接收消息.当mySendingServer发送消息时,mySendingServer上的MSMQ日志中会出现一条条目,其中显示:但是,myReceivingServer,在MSMQ日志中有

随机推荐

  1. 从C到C#的zlib(如何将byte []转换为流并将流转换为byte [])

    我的任务是使用zlib解压缩数据包(已接收),然后使用算法从数据中生成图片好消息是我在C中有代码,但任务是在C#中完成C我正在尝试使用zlib.NET,但所有演示都有该代码进行解压缩(C#)我的问题:我不想在解压缩后保存文件,因为我必须使用C代码中显示的算法.如何将byte[]数组转换为类似于C#zlib代码中的流来解压缩数据然后如何将流转换回字节数组?

  2. 为什么C标准使用不确定的变量未定义?

    垃圾价值存储在哪里,为什么目的?解决方法由于效率原因,C选择不将变量初始化为某些自动值.为了初始化这些数据,必须添加指令.以下是一个例子:产生:虽然这段代码:产生:你可以看到,一个完整的额外的指令用来移动1到x.这对于嵌入式系统来说至关重要.

  3. 如何使用命名管道从c调用WCF方法?

    更新:通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的:我有以下WCF服务我输出添加5行,所以我知道服务器是否处理了请求与否.我有一个.NET客户端,我曾经测试这一切,一切正常工作预期.现在我想为这个做一个非托管的C客户端.我想出了如何得到管道的名称,并写信给它.我从here下载了协议我可以写信给管道,但我看不懂.每当我尝试读取它,我得到一个ERROR_broKEN_P

  4. “这”是否保证指向C中的对象的开始?

    我想使用fwrite将一个对象写入顺序文件.班级就像当我将一个对象写入文件时.我正在游荡,我可以使用fwrite(this,sizeof(int),2,fo)写入前两个整数.问题是:这是否保证指向对象数据的开始,即使对象的最开始可能存在虚拟表.所以上面的操作是安全的.解决方法这提供了对象的地址,这不一定是第一个成员的地址.唯一的例外是所谓的标准布局类型.从C11标准:(9.2/20)Apointe

  5. c – 编译单元之间共享的全局const对象

    当我声明并初始化一个const对象时.两个cpp文件包含此标头.和当我构建解决方案时,没有链接错误,你会得到什么如果g_Const是一个非const基本类型!PrintInUnit1()和PrintInUnit2()表明在两个编译单元中有两个独立的“g_Const”具有不同的地址,为什么?

  6. 什么是C名称查找在这里? (&amp;GCC对吗?)

    为什么在第三个变体找到func,但是在实例化的时候,原始变体中不合格查找找不到func?解决方法一般规则是,任何不在模板定义上下文中的内容只能通过ADL来获取.换句话说,正常的不合格查找仅在模板定义上下文中执行.因为在定义中间语句时没有声明func,并且func不在与ns::type相关联的命名空间中,所以代码形式不正确.

  7. c – 在输出参数中使用auto

    有没有办法在这种情况下使用auto关键字:当然,不可能知道什么类型的.因此,解决方案应该是以某种方式将它们合并为一个句子.这可用吗?解决方法看起来您希望默认初始化给定函数期望作为参数的类型的对象.您无法使用auto执行此操作,但您可以编写一个特征来提取函数所需的类型,然后使用它来声明您的变量:然后你就像这样使用它:当然,只要你重载函数,这一切都会失败.

  8. 在C中说“推动一切浮动”的确定性方式

    鉴于我更喜欢将程序中的数字保留为int或任何内容,那么使用这些数字的浮点数等效的任意算术最方便的方法是什么?说,我有我想写通过将转换放在解析的运算符树叶中,无需将表达式转化为混乱是否可以使用C风格的宏?应该用新的类和重载操作符完成吗?解决方法这是一个非常复杂的表达.更好地给它一个名字:现在当您使用整数参数调用它时,由于参数的类型为double,因此使用常规的算术转换将参数转换为double用C11lambda……

  9. objective-c – 如何获取未知大小的NSArray的第一个X元素?

    在objectiveC中,我有一个NSArray,我们称之为NSArray*largeArray,我想要获得一个新的NSArray*smallArray,只有第一个x对象…

  10. c – Setprecision是混乱

    我只是想问一下setprecision,因为我有点困惑.这里是代码:其中x=以下:方程的左边是x的值.1.105=1.10应为1.111.115=1.11应为1.121.125=1.12应为1.131.135=1.14是正确的1.145=1.15也正确但如果x是:2.115=2.12是正确的2.125=2.12应为2.13所以为什么在一定的价值是正确的,但有时是错误的?请启发我谢谢解决方法没有理由期望使用浮点系统可以正确地表示您的帖子中的任何常量.因此,一旦将它们存储在一个双变量中,那么你所拥有的确切的一

返回
顶部