Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,125 | Comments: 45,492

filter by tags archive

Unmanaged API “fun”, finding out MSMQ subqueues names in C#

time to read 26 min | 5169 words

I needed to get a list of subqueues of a queue, and there is no way of actually doing that in managed code. I decided that I can still use P/Invoke and just make the appropriate unmanaged calls. In hindsight, it would have been significantly simpler to just build an unmanaged DLL in C++/CLR, but I was already too deep, and I can never remember how to properly compile a C++ app anymore.

I finally had to slap myself a couple of times and remind me that I was a C++ developer for a long time, and I damn well should remember how to treat memory like it was something both sacred and abused. I had tested that on a Windows 2008 64 bits machine. During this project, I also found out that there is basically no information at all about this sort of thing, so I am putting the code here.

public class MsmqUtil
    internal const int PROPID_MGMT_QUEUE_SUBQUEUE_NAMES = 27;
    internal const ushort VT_NULL = 1;
    public static unsafe string[] GetMsmqSubQueueNames(string queueFormatName)
        var props = new MQMGMTPROPS {cProp = 1};
        var variant = new MQPROPVariant {vt = VT_NULL};
            props.aPropID = Marshal.AllocHGlobal(sizeof (int));
            Marshal.WriteInt32(props.aPropID, PROPID_MGMT_QUEUE_SUBQUEUE_NAMES);
            props.aPropVar = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (MQPROPVariant)));
            Marshal.StructureToPtr(new MQPROPVariant {vt = VT_NULL}, props.aPropVar, false);
            props.status = Marshal.AllocHGlobal(sizeof (int));
            Marshal.WriteInt32(props.status, 0);
            var result = MQMgmtGetInfo(null, "queue=" + queueFormatName, ref props);
            if (result != 0)
                throw new Win32Exception(result);
            if (Marshal.ReadInt32(props.status) != 0)
                return null;
            variant = (MQPROPVariant) Marshal.PtrToStructure(props.aPropVar, typeof (MQPROPVariant));
            var subQueues = new List<string>();
            for (int i = 0; i < variant.Val.calpwstr.cElems; i++)
                var item = new string(variant.Val.calpwstr.pElems[i]);
            return subQueues.ToArray();
            if (variant.vt != VT_NULL)
                for (var i = 0; i < variant.Val.calpwstr.cElems; i++)
    internal static extern int MQMgmtGetInfo([MarshalAs(UnmanagedType.BStr)] string computerName,
                                             [MarshalAs(UnmanagedType.BStr)] string objectName,
                                             ref MQMGMTPROPS mgmtProps);
    internal static extern unsafe int MQFreeMemory(void* queue);
    internal struct CALPWSTR
        public uint cElems;
        public unsafe char** pElems;
    internal struct MQMGMTPROPS
        public uint cProp;
        public IntPtr aPropID;
        public IntPtr aPropVar;
        public IntPtr status;
    [StructLayout(LayoutKind.Sequential, Size = 16)]
    internal struct MQPROPVariant
        public ushort vt;
        public ushort wReserved1;
        public ushort wReserved2;
        public ushort wReserved3;
        public UnionedVariant Val; //8
    [StructLayout(LayoutKind.Explicit, Size = 8)]
    internal struct UnionedVariant
        [FieldOffset(0)] public uint ulVal; /* VT_UI4    */
        [FieldOffset(0)] public CALPWSTR calpwstr; /* VT_VECTOR | VT_LPWSTR  */



Thank you for sharing, too bad subqueues are not supported in MSMQ 3.0.

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 13 hours from now
  2. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 4 days from now
  3. The design of RavenDB 4.0: Voron has a one track mind - 5 days from now
  4. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 6 days from now
  5. The design of RavenDB 4.0: Separation of indexes and documents - 7 days from now

And 11 more posts are pending...

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    05 May 2016 - Physically segregating collections
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats