C# 在不重新启动应用程序的情况下处理URL协议
我的问题都是关于URL协议的。 我已经注册了一个名为mcm的URL协议,但我注意到每次我从任何web浏览器运行它时,t都会创建一个新的应用程序实例。有没有办法在已经运行的实例中处理协议请求 例如,当uTorrent使用torrent协议时,它会立即处理请求,而无需再次运行应用程序。我真的找不到任何有趣的东西,所以我在这里问 以下是我用于注册协议的代码:C# 在不重新启动应用程序的情况下处理URL协议,c#,url,protocols,C#,Url,Protocols,我的问题都是关于URL协议的。 我已经注册了一个名为mcm的URL协议,但我注意到每次我从任何web浏览器运行它时,t都会创建一个新的应用程序实例。有没有办法在已经运行的实例中处理协议请求 例如,当uTorrent使用torrent协议时,它会立即处理请求,而无需再次运行应用程序。我真的找不到任何有趣的东西,所以我在这里问 以下是我用于注册协议的代码: private static void RegisterUrlProtocol() { UnregisterUrlProtocol();
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();
}
}
以及读取参数的代码:
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;
}
任何帮助都将不胜感激:)
问候。您可以使用互斥来检测已在运行的应用程序实例,并通过命名管道将数据发送到现有实例 希望下面的例子有帮助。 您可以将命名管道对象(在本例中为字符串)替换为您喜欢的任何可序列化对象 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
}
}
namespace SingleInstanceNP
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO.Pipes;
使用System.Runtime.Serialization.Formatters.Binary;
使用系统线程;
使用System.IO;
公共类名称管道:IDisposable
{
#区域属性和属性
私有字符串_pipeName;
私有名称PipeServerStream\u pipeServer;
私人住宅;
私有线程(u线程),;
私人住宅开始营业;
#端区
#区域构造函数
公共名称管道(名称类型管道类型)
{
_已处理=错误;
_开始=错误;
_pipeName=pipeType.ToString();
_螺纹=新螺纹(主);
_SetApartmentState(ApartmentState.STA);
_thread.Name=“NamePipe:”+pipeType.ToString()+“thread”;
_thread.IsBackground=true;
}
~NamedPipe()
{
处置();
}
#端区
#地区活动
公共代表无效请求(T);
公开活动的请求;
#端区
#区域公共方法
公共静态无效发送(名称类型pipeType,T)
{
使用(var npc=new NamedPipeClientStream(“.”,pipeType.ToString(),PipeDirection.Out))
{
var bf=新的二进制格式化程序();
npc.Connect();
bf.序列化(npc,t);
}
}
公共静态T接收器(名称类型pipeType)
{
使用(var nps=new NamedPipeServerStream(pipeType.ToString(),PipeDirection.In))
{
返回接收(nps);
}
}
公开作废开始()
{
如果(!\u已处置&!\u已启动)
{
_开始=真;
_thread.Start();
}
}
公共停车场()
{
_开始=错误;
如果(_pipeServer!=null)
{
_pipeServer.Close();
//处理将在线程上发生
}
}
公共空间处置()
{
_这是真的;
停止();
if(OnRequest!=null)
OnRequest=null;
}
#端区
私有void Main()
{
而(_启动&!_处置)
{
尝试
{
使用(_pipeServer=new NamedPipeServerStream(_pipeName))
{
T=接收(_pipeServer);
if(OnRequest!=null&&u已启动)
应请求(t);
}
}
捕获(线程异常)
{ }
捕获(System.IO.IOException iox)
{
WriteLine(“错误:{0}”,iox.Message);
睡眠(时间跨度从秒(30));
}
捕获(例外情况除外)
{
WriteLine(“错误:{0}”,例如Message);
返回;
}
}
}
专用静态T接收(NamedPipeServerStream nps)
{
var bf=新的二进制格式化程序();
尝试
{
nps.WaitForConnection();
var obj=bf.反序列化(nps);
if(obj是T)
返回(T)obj;
}
//捕获在管道处于活动状态时引发的IOException
//断开或断开。
捕获(IOE异常)
{
WriteLine(“错误:{0}”,e.Message);
}
返回默认值(T);
}
#区域枚举
公共枚举名称类型
{
管道类型1
}
#端区
}
}
Program.cs
请将应用程序GUID归功于
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
运用系统反思;
使用系统线程;
名称空间SingleInstanceNP
{
静态类程序
{
///
///应用程序的主要入口点。
///
[状态线程]
静态void Main()
{
//获取AssemblyInfo.cs中定义的应用程序GUID
字符串appGuid=((GuidAttribute)Assembly.getExecutionGassembly().GetCustomAttributes(typeof(GuidAttribute),false.GetValue(0)).Value.ToString();
//全局互斥体的唯一id-全局前缀表示它对计算机是全局的
string mutexId=string.Format(“全局\\{{0}}}”,appGuid);
使用(var mutex=new mutex(false,mutexId))
{
尝试
{
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();
}
}
}
}
}
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);
}
}
}