Cannot determine whether a queue with the specified format name exists
Asked Answered
M

5

18

I get the exception when executing the following code. Any ideas what is wrong?

string queueName = "FormatName:Direct=TCP:1.1.1.1\\Private$\\test";
MessageQueue queue;

if (MessageQueue.Exists(queueName))
     queue = new System.Messaging.MessageQueue(queueName);
else queue = MessageQueue.Create(queueName);

queue.Send(sWriter.ToString());

Edit: Here is the exception message and first line of stacktrace

Cannot determine whether a queue with the specified format name exists.
at System.Messaging.MessageQueue.Exists(String path)

It works for a local queue by the way.

Marbling answered 16/12, 2009 at 14:12 Comment(1)
provide exception message pleaseLyautey
M
41

From your sample, it looks like you're trying to check whether a remote private queue exists, but as the MessageQueue.Exists documentation says:

Exists cannot be called to verify the existence of a remote private queue.

Trying to do so will produce an InvalidOperationException.


If you really need this information for your workflow, you can use the MessageQueue. GetPrivateQueuesByMachine method and iterate the results to find a match. If you do, I recommend reading Are Remote MSMQ Queues Reliable?, which discusses this approach in some depth.

This post from the excellent "MSMQ from the plumber's mate" blog suggests another alternative: don't even check whether your queues exist, "but instead handle the non-delivery of the message should it turn out that the queue doesn't exist." (You'll need to track administration queues and/or dead-letter queues, but you should probably be doing that anyway.)

Mcqueen answered 16/12, 2009 at 14:25 Comment(0)
D
4

Try this...

  public static bool IsQueueAvailable(string queueName)
   {
        var queue = new MessageQueue(queueName);
        try
        {
            queue.Peek(new TimeSpan(0, 0, 5));
            return true;
        }
        catch (MessageQueueException ex)
        {
            return ex.Message.StartsWith("Timeout");
        }
    }

If the queue doesn't exist or if the account running the app doesn't have sufficient rights to get to it, the exception message clearly states so.

AND, this would work with both FormatName and the usual queue path.

Dardanus answered 7/9, 2011 at 0:11 Comment(2)
When testing, I was getting the timeout when the Queue was empty.Faye
@Faye check my combined answer: https://mcmap.net/q/650807/-cannot-determine-whether-a-queue-with-the-specified-format-name-existsMiltiades
M
4

I ended up with the answers from Svix, Erwin van Dijk and Joseph Daigle combined. Additionally I checked for ArgumentException:

    /// <summary>
    /// Checks if a (remote) Microsoft Message Queue is available
    /// </summary>
    /// <param name="queueName">The name of the Message Queue.</param>
    /// <returns>Returns true if the queue is available otherwise false.</returns>
    public static bool IsQueueAvailable(string queueName)
    {
        MessageQueue queue;
        try
        {
            queue = new MessageQueue(queueName);
            queue.Peek(new TimeSpan(0, 0, 5)); // wait max. 5 sec. to recieve first message from queue (reduce if necessary)
            return true;
        }
        catch (Exception ex)
        {
            if(ex is ArgumentException)
            {   // the provided queue name is wrong.
                return false;
            }
            else if (ex is MessageQueueException)
            {   // if message queue exception occurs either the queue is avialable but without entries (check for peek timeout) or the queue does not exist or you don't have access.
                return (((MessageQueueException)ex).MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout);
            }
            // any other error occurred.
            return false;
        }
    }
Miltiades answered 6/1, 2016 at 12:40 Comment(0)
H
2

The answer above with checking the exception message does work on systems that raise English-exceptions. My system raises Dutch-exceptions. I get "De time-out voor de gevraagde bewerking is verstreken." So it's not a very robust solutions The exception has a property MessageQueueErrorCode that should be used to check whether or not an IOTimeout occurred.

So it's better to use

return (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout);

instead of:

return ex.Message.StartsWith("Timeout");
Hoatzin answered 28/2, 2013 at 8:22 Comment(0)
H
0

You cannot use the Exists method on a remote queue, so you have to impersonate a user on that remote machine:

//usings
using System;
using System.Messaging;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;

//Declaring the advapi32.dll
 [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
            string lpszUsername,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            out IntPtr phToken);

private void IterateRemoteMQ()
    {
        IntPtr userToken = IntPtr.Zero;

        bool success = LogonUser(
          "REMOTE_USERNAME", //Username on the remote machine
          ".",  //Domain, if not using AD, Leave it at "."
          "PASSWORD",  //Password for the username on the remote machine
          9, //Means we're using new credentials, otherwise it will try to impersonate a local user
          0,
          out userToken);

        if (!success)
        {
            throw new SecurityException("Logon user failed");
        }
        //Go through each queue to see if yours exists, or do some operation on that queue.
        using (WindowsIdentity.Impersonate(userToken))
        {
            MessageQueue[] Queues = MessageQueue.GetPrivateQueuesByMachine("192.168.1.10");
            foreach (MessageQueue mq in Queues)
            {
                string MSMQ_Name = mq.QueueName;
            }
        }
Hendley answered 14/1, 2014 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.