gpt4 book ai didi

c# - 在不重启应用程序的情况下处理 URL 协议(protocol)

转载 作者:可可西里 更新时间:2023-11-01 08:47:30 25 4
gpt4 key购买 nike

我的问题都是关于 URL 协议(protocol)的。

我已经注册了一个名为 mcm 的 URL 协议(protocol),但我注意到每次我从任何网络浏览器运行它时,都会创建一个新的应用程序实例。有没有办法在已经运行的实例中处理协议(protocol)请求?

例如,当 uTorrent 使用 torrent 协议(protocol)时,它会立即处理请求,而无需再次运行该应用程序。我真的找不到任何有趣的东西,所以我在这里问...

这是我用来注册协议(protocol)的代码:

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

任何帮助将不胜感激:)问候。

最佳答案

您可以使用 Mutex 来检测已在运行的应用程序实例,并通过命名管道将数据发送到现有实例。

希望以下示例对您有所帮助。您可以将命名管道对象(在本例中为字符串)换成您喜欢的任何可序列化对象。

命名管道.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
}
}

程序.cs请将 APP GUID 归功于 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);
}
}
}

关于c# - 在不重启应用程序的情况下处理 URL 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9079947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com