You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

IPCService.cs 2.9 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System;
  2. using System.IO.Pipes;
  3. using System.Net;
  4. using System.Text;
  5. namespace Shadowsocks.Controller
  6. {
  7. class RequestAddUrlEventArgs : EventArgs
  8. {
  9. public readonly string Url;
  10. public RequestAddUrlEventArgs(string url)
  11. {
  12. this.Url = url;
  13. }
  14. }
  15. internal class IPCService
  16. {
  17. private const int INT32_LEN = 4;
  18. private const int OP_OPEN_URL = 1;
  19. private static readonly string PIPE_PATH = $"Shadowsocks\\{Program.ExecutablePath.GetHashCode()}";
  20. public event EventHandler<RequestAddUrlEventArgs> OpenUrlRequested;
  21. public async void RunServer()
  22. {
  23. byte[] buf = new byte[4096];
  24. while (true)
  25. {
  26. using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_PATH))
  27. {
  28. await stream.WaitForConnectionAsync();
  29. await stream.ReadAsync(buf, 0, INT32_LEN);
  30. int opcode = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buf, 0));
  31. if (opcode == OP_OPEN_URL)
  32. {
  33. await stream.ReadAsync(buf, 0, INT32_LEN);
  34. int strlen = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buf, 0));
  35. await stream.ReadAsync(buf, 0, strlen);
  36. string url = Encoding.UTF8.GetString(buf, 0, strlen);
  37. OpenUrlRequested?.Invoke(this, new RequestAddUrlEventArgs(url));
  38. }
  39. stream.Close();
  40. }
  41. }
  42. }
  43. private static (NamedPipeClientStream, bool) TryConnect()
  44. {
  45. NamedPipeClientStream pipe = new NamedPipeClientStream(PIPE_PATH);
  46. bool exist;
  47. try
  48. {
  49. pipe.Connect(10);
  50. exist = true;
  51. }
  52. catch (TimeoutException)
  53. {
  54. exist = false;
  55. }
  56. return (pipe, exist);
  57. }
  58. public static bool AnotherInstanceRunning()
  59. {
  60. (NamedPipeClientStream pipe, bool exist) = TryConnect();
  61. pipe.Dispose();
  62. return exist;
  63. }
  64. public static void RequestOpenUrl(string url)
  65. {
  66. (NamedPipeClientStream pipe, bool exist) = TryConnect();
  67. if(!exist) return;
  68. byte[] opAddUrl = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(OP_OPEN_URL));
  69. pipe.Write(opAddUrl, 0, INT32_LEN); // opcode addurl
  70. byte[] b = Encoding.UTF8.GetBytes(url);
  71. byte[] blen = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(b.Length));
  72. pipe.Write(blen, 0, INT32_LEN);
  73. pipe.Write(b, 0, b.Length);
  74. pipe.Close();
  75. pipe.Dispose();
  76. }
  77. }
  78. }