2012-01-31 16 views
9

Moje pytanie dotyczy wszystkich protokołów URL.Obsługa protokołu URL bez ponownego uruchamiania aplikacji

Zarejestrowałem URL Protokół nazywane MCM, ale zauważyłem, że za każdym razem go uruchomić z poziomu dowolnej przeglądarki internetowej, t tworzy nową instancję aplikacji. Czy istnieje sposób na obsłużenie żądania protokołu w już działającej instancji?

Na przykład, gdy uTorrent używa protokołu torrent Obsługuje żądanie natychmiast, bez ponownego uruchamiania aplikacji. Ja naprawdę nie mogłem znaleźć nic ciekawego o nim, więc pytam tutaj ...

Oto kod używać do rejestrowania protokołu:

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

a kod czytać argumenty:

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

Każda pomoc byłaby bardzo doceniana :) Pozdrowienia.

+5

założę jeśli spojrzeć byś zobacz drugą instancję ładowania, wykryj istniejącą instancję i komunikuj się z nią przez I PC nowa linia poleceń –

+0

zobaczyć również http://stackoverflow.com/questions/917883/c-sharp-how-to-single-instance-application-that-accepts-new-parameters –

+0

Oh I rzeczywiście znaleźć co mam chciał. Dzięki Alex :) –

Odpowiedz

4

Można użyć Mutex wykryć instancję aplikacji, która jest już uruchomiony i wysyłać dane do istniejącego na przykład za pośrednictwem nazwanych potoków.

Mam nadzieję, że poniższy przykład pomoże. można zamienić obiekt nazwanych potoków (w tym przypadku ciąg) dla dowolnego obiektu serializowalnego, który ci się podoba.

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 proszę dać kredyt dla APP GUID do 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: to nie jest kompletna odpowiedź –

+0

Proszę zobaczyć edycję. Ponieważ potrzebuję przedstawiciela, przedstawiłem działający przykład. Również @JohnSaunders nie wiedziałem "Każda pomoc" oznaczało, że musi to być kod –

+0

Teraz wiesz: kod jest bardzo preferowany –

Powiązane problemy