2012-01-31 14 views
9

Mi pregunta es sobre protocolos de URL.Tratamiento del protocolo URL sin reinicios de la aplicación

He registrado un protocolo URL llama mcm, pero me di cuenta que cada vez que lo ejecuto desde cualquier navegador web, t crea una nueva instancia de la aplicación. ¿Hay alguna forma de manejar la solicitud de protocolo en una instancia ya en ejecución?

Por ejemplo, cuando uTorrent está utilizando el protocolo torrent Maneja la solicitud inmediatamente sin ejecutar la aplicación nuevamente. Realmente no pude encontrar nada interesante al respecto, por lo que estoy pidiendo aquí ...

Este es el código que utilizo para registrar el protocolo:

private static void RegisterUrlProtocol() 
{ 
    UnregisterUrlProtocol(); 

    RegistryKey rKey = Registry.ClassesRoot.OpenSubKey(UrlProtocol, true); 
    if (rKey == null) 
    { 
     rKey = Registry.ClassesRoot.CreateSubKey(UrlProtocol); 
     rKey.SetValue("", "URL: MazCraft Protocol"); 
     rKey.SetValue("URL Protocol", ""); 

     rKey = rKey.CreateSubKey(@"shell\open\command"); 
     rKey.SetValue("", "\"" + Application.ExecutablePath + "\" %1"); 
    } 

    if (rKey != null) 
    { 
     rKey.Close(); 
    } 
} 

Y el código para leer los argumentos:

private static bool CheckForProtocolMessage() 
{ 
    string[] arguments = Environment.GetCommandLineArgs(); 

    if (arguments.Length > 1) 
    { 
     string[] args = arguments[1].Split(':'); 
     args[1] = args[1].Replace("//", ""); 

     if (args[0].Trim().ToUpper() == "MCM" && args.Length > 1) 
     { 
      string[] actionDetail = args[1].Split('='); 

      if (actionDetail[0].Trim().ToUpper() == "INSTALL" && actionDetail.Length > 1) 
      { 
       string id = actionDetail[1].Trim().Replace("/", ""); 

       Funcs.ID = id; 

       return true; 
      } 
     } 
    } 

    return false; 
} 

Cualquier ayuda sería muy apreciada :) Saludos.

+5

apuesto si se mira lo haría ver una segunda instancia de carga utorrent, detectar una instancia existente de sí mismo y comunicarse a través de I PC la nueva línea de comando –

+0

También vea http://stackoverflow.com/questions/917883/c-sharp-how-to-single-instance-application-hat-accepts-new-parameters –

+0

Oh, en realidad encontré lo que he querido. Gracias Alex :) –

Respuesta

4

Puede usar un Mutex para detectar una instancia de la aplicación que ya se está ejecutando y enviar los datos a la instancia existente a través de Canalizaciones con nombre.

Espero que el siguiente ejemplo ayude. puede intercambiar el objeto de canalización con nombre (en este caso cadena) para cualquier objeto serializable que desee.

NamedPipe.cs

namespace SingleInstanceNP 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.IO.Pipes; 
    using System.Runtime.Serialization.Formatters.Binary; 
    using System.Threading; 
    using System.IO; 


    public class NamedPipe<T> : IDisposable 
    { 
     #region Attribute and Properties 

     private string _pipeName; 
     private NamedPipeServerStream _pipeServer; 
     private bool _disposed; 
     private Thread _thread; 
     private bool _started; 

     #endregion 

     #region Constructors 

     public NamedPipe(NameTypes pipeType) 
     { 
      _disposed = false; 
      _started = false; 
      _pipeName = pipeType.ToString(); 
      _thread = new Thread(Main); 
      _thread.SetApartmentState(ApartmentState.STA); 
      _thread.Name = "NamePipe: " + pipeType.ToString() + " Thread"; 
      _thread.IsBackground = true; 
     } 

     ~NamedPipe() 
     { 
      Dispose(); 
     } 

     #endregion 

     #region Events 

     public delegate void Request(T t); 
     public event Request OnRequest; 

     #endregion 

     #region Public Methods 

     public static void Send(NameTypes pipeType, T t) 
     { 
      using (var npc = new NamedPipeClientStream(".", pipeType.ToString(), PipeDirection.Out)) 
      { 
       var bf = new BinaryFormatter(); 
       npc.Connect(); 
       bf.Serialize(npc, t); 
      } 
     } 

     public static T Recieve(NameTypes pipeType) 
     { 
      using (var nps = new NamedPipeServerStream(pipeType.ToString(), PipeDirection.In)) 
      { 
       return Recieve(nps); 
      } 
     } 

     public void Start() 
     { 
      if (!_disposed && !_started) 
      { 
       _started = true; 
       _thread.Start(); 
      } 
     } 

     public void Stop() 
     { 
      _started = false; 

      if (_pipeServer != null) 
      { 
       _pipeServer.Close(); 
       // disposing will occur on thread 
      } 
     } 

     public void Dispose() 
     { 
      _disposed = true; 
      Stop(); 

      if (OnRequest != null) 
       OnRequest = null; 
     } 

     #endregion 

     private void Main() 
     { 
      while (_started && !_disposed) 
      { 
       try 
       { 
        using (_pipeServer = new NamedPipeServerStream(_pipeName)) 
        { 
         T t = Recieve(_pipeServer); 

         if (OnRequest != null && _started) 
          OnRequest(t); 
        } 
       } 
       catch (ThreadAbortException) 
       { } 
       catch (System.IO.IOException iox) 
       { 
        Console.WriteLine("ERROR: {0}", iox.Message); 
        Thread.Sleep(TimeSpan.FromSeconds(30)); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("ERROR: {0}", ex.Message); 
        return; 
       } 
      } 
     } 

     private static T Recieve(NamedPipeServerStream nps) 
     { 
      var bf = new BinaryFormatter(); 

      try 
      { 
       nps.WaitForConnection(); 

       var obj = bf.Deserialize(nps); 

       if (obj is T) 
        return (T)obj; 
      } 
      // Catch the IOException that is raised if the pipe is 
      // broken or disconnected. 
      catch (IOException e) 
      { 
       Console.WriteLine("ERROR: {0}", e.Message); 
      } 
      return default(T); 
     } 

     #region Enums 

     public enum NameTypes 
     { 
      PipeType1 
     } 

     #endregion 
    } 
} 

Program.cs favor dar crédito para la APP GUID para What is a good pattern for using a Global Mutex in C#?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Reflection; 
using System.Threading; 

namespace SingleInstanceNP 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      // get application GUID as defined in AssemblyInfo.cs 
      string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString(); 

      // unique id for global mutex - Global prefix means it is global to the machine 
      string mutexId = string.Format("Global\\{{{0}}}", appGuid); 

      using (var mutex = new Mutex(false, mutexId)) 
      { 
       try 
       { 
        if (!mutex.WaitOne(0, false)) 
        { 
         //signal existing app via named pipes 

         NamedPipe<string>.Send(NamedPipe<string>.NameTypes.PipeType1, "test"); 

         Environment.Exit(0); 
        } 
        else 
        { 
         // handle protocol with this instance 
         Application.Run(new Form1()); 

        } 
       } 
       finally 
       { 
        mutex.ReleaseMutex(); 
       } 
      } 
     } 
    } 
} 

Form1.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace SingleInstanceNP 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      // start listening for named pipe connections 
      var namedPipeString = new NamedPipe<string>(NamedPipe<string>.NameTypes.PipeType1); 
      namedPipeString.OnRequest += new NamedPipe<string>.Request(namedPipeString_OnRequest); 
      namedPipeString.Start(); 
     } 

     void namedPipeString_OnRequest(string t) 
     { 
      MessageBox.Show(t); 
     } 
    } 
} 
+1

-1: esta no es una respuesta completa –

+0

Consulte edición. Como necesito representante, he proporcionado un ejemplo de trabajo. También @JohnSaunders no sabía "Cualquier ayuda" significaba que tenía que ser el código –

+0

Ahora, ya sabes: el código es muy preferido –

Cuestiones relacionadas