2009-12-16 10 views
14

Obtengo la excepción al ejecutar el siguiente código. ¿Alguna idea de lo que está mal?No se puede determinar si existe una cola con el nombre de formato especificado.

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()); 

Editar: Aquí está el mensaje de excepción y la primera línea de StackTrace

No se puede determinar si existe una cola con el nombre de formato especificado .
en System.Messaging.MessageQueue.Exists (String path)

funciona para una cola local por el camino.

+1

proporcionan mensaje de excepción favor –

Respuesta

35

Desde su muestra, parece que usted está tratando de comprobar si existe una cola privada a distancia, pero a medida que la documentación MessageQueue.Exists dice:

existe no se puede llamar para verificar la existencia de una privada remota cola.

Si lo hace, se generará un InvalidOperationException.


Si realmente necesita esta información para su flujo de trabajo, puede utilizar el método MessageQueue. GetPrivateQueuesByMachine e iterar los resultados para encontrar una coincidencia. Si lo hace, le recomiendo que lea Are Remote MSMQ Queues Reliable?, que analiza este enfoque con cierta profundidad.

This post from the excellent "MSMQ from the plumber's mate" blog sugiere otra alternativa: ni siquiera compruebe si existen colas, "pero en su lugar, controle la falta de entrega del mensaje en caso de que la cola no exista". (Tendrá que realizar un seguimiento de las colas de administración y/o colas de mensajes no entregados, pero probablemente debería estar haciendo eso de todos modos.)

4

probar este ...

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"); 
     } 
    } 

Si no existe la cola o si la cuenta que ejecuta la aplicación no tiene suficientes derechos para acceder a ella, el mensaje de excepción lo establece claramente.

Y, esto funcionaría tanto con FormatName como con la ruta habitual de la cola.

+1

Cuando se prueba, que estaba recibiendo el tiempo de espera cuando la cola estaba vacío. – NealWalters

+0

@NealWalters verifique mi respuesta combinada: http://stackoverflow.com/a/34633405/1306012 –

2

La respuesta anterior al verificar el mensaje de excepción funciona en sistemas que generan excepciones en inglés. Mi sistema plantea excepciones holandesas. Me aparece "De time-out voor de gevraagde bewerking is verstreken". Por lo tanto, no es una solución muy robusta. La excepción tiene una propiedad MessageQueueErrorCode que se debe usar para verificar si se produjo o no un IOTimeout.

Así que es mejor utilizar

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

en lugar de:

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

No se puede utilizar el método existe en una cola remota, por lo que tiene que hacerse pasar por un usuario en esa máquina remota:

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

que terminó con las respuestas de Svix, Erwin van Dijk y Joseph Daigle combinado. Además he comprobado para 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; 
     } 
    } 
Cuestiones relacionadas