C# 无法确定是否存在具有指定格式名称的队列

C# 无法确定是否存在具有指定格式名称的队列,c#,exception,msmq,C#,Exception,Msmq,我在执行以下代码时遇到异常。你知道怎么了吗 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);

我在执行以下代码时遇到异常。你知道怎么了吗

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());
编辑: 这是异常消息和stacktrace的第一行

无法确定是否存在具有指定格式名称的队列 存在。
位于System.Messaging.MessageQueue.exists(字符串路径)


顺便说一句,它适用于本地队列。

从您的示例中,看起来您正在尝试检查是否存在远程专用队列,但正如文档所述:

无法调用Exists来验证 存在远程专用队列

尝试这样做将产生一个
InvalidOperationException


如果您的工作流确实需要这些信息,您可以使用该方法并迭代结果以找到匹配项。如果你愿意,我建议你阅读,这篇文章对这种方法进行了深入的讨论

建议另一种选择:甚至不检查队列是否存在,“而是在队列不存在的情况下处理未传递的消息。”(您需要跟踪管理队列和/或死信队列,但您可能无论如何都应该这样做。)

试试这个

  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");
        }
    }
如果队列不存在,或者运行应用程序的帐户没有足够的权限访问该队列,则异常消息会明确说明这一点


而且,这将同时适用于FormatName和常规队列路径。

以上检查异常消息的答案确实适用于引发英语异常的系统。我的系统引发了荷兰例外。我得到“De timeout voor De gevraagde bewerking is verstreken.”所以这不是一个非常健壮的解决方案异常有一个属性MessageQueueErrorCode,应该用来检查是否发生了IOTimeout

所以最好使用

return (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout);
而不是:

return ex.Message.StartsWith("Timeout");

无法在远程队列上使用Exists方法,因此必须模拟该远程计算机上的用户:

//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;
            }
        }

我最终得到了来自、和的答案。此外,我还检查了
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;
        }
    }
//
///检查(远程)Microsoft消息队列是否可用
/// 
///消息队列的名称。
///如果队列可用,则返回true;否则返回false。
公共静态bool IsQueueAvailable(字符串queueName)
{
消息队列;
尝试
{
队列=新消息队列(队列名称);
queue.Peek(新时间跨度(0,0,5));//最多等待5秒以接收来自队列的第一条消息(如有必要,减少)
返回true;
}
捕获(例外情况除外)
{
if(ex为异常)
{//提供的队列名称错误。
返回false;
}
else if(ex为MessageQueueException)
{//如果发生消息队列异常,则队列是可访问的,但没有条目(检查peek timeout),或者队列不存在,或者您没有访问权限。
返回(((MessageQueueException)ex.MessageQueueErrorCode==MessageQueueErrorCode.IOTimeout);
}
//发生任何其他错误。
返回false;
}
}

请提供异常消息测试时,我在队列为空时获得超时。@请检查我的组合答案: