From 50023a88ecd6bccafac83a20f296df94df947621 Mon Sep 17 00:00:00 2001 From: Rob Janssen Date: Tue, 15 Oct 2013 08:31:10 +0000 Subject: [PATCH] * Switched to named pipes for IPC * Bumped to 0.5.0 --- Fop2DD/Core/DDCore.cs | 19 +++++ Fop2DD/Core/IPC/DDPipeClient.cs | 45 ++++++++++++ .../IPC/DDPipeMessageReceivedEventArgs.cs | 14 ++++ Fop2DD/Core/IPC/DDPipeServer.cs | 70 +++++++++++++++++++ Fop2DD/Fop2DD.csproj | 3 + Fop2DD/Program.cs | 8 +-- Fop2DD/Properties/AssemblyInfo.cs | 4 +- Fop2DD/setup.iss | 6 +- 8 files changed, 159 insertions(+), 10 deletions(-) create mode 100644 Fop2DD/Core/IPC/DDPipeClient.cs create mode 100644 Fop2DD/Core/IPC/DDPipeMessageReceivedEventArgs.cs create mode 100644 Fop2DD/Core/IPC/DDPipeServer.cs diff --git a/Fop2DD/Core/DDCore.cs b/Fop2DD/Core/DDCore.cs index a4fccef..10b4939 100644 --- a/Fop2DD/Core/DDCore.cs +++ b/Fop2DD/Core/DDCore.cs @@ -2,6 +2,7 @@ using Fop2DD.Core.Common; using Fop2DD.Core.Connection; using Fop2DD.Core.Hotkeys; +using Fop2DD.Core.IPC; using Fop2DD.Core.Logging; using Fop2DD.Core.Systray; using System; @@ -20,6 +21,7 @@ public class DDCore : IDisposable private ToolStripMenuItem _fop2webinterface; private ToolStripMenuItem _fop2userportal; + private DDPipeServer _pipeserver; private IDDLogger logger = DDLogManager.GetLogger(typeof(DDCore)); @@ -43,6 +45,23 @@ public DDCore() _hotkeymanager.DialRequest += event_DialRequest; _connectionmanager.RegisterListener(_notifyicon); + + _pipeserver = new DDPipeServer(); + _pipeserver.MessageReceived += (s, e) => { + this.DialFromCommandlineArgs(e.Data.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)); + }; + _pipeserver.Listen(GetIPCPipeName()); + } + + public static void SendIPCPessage(string message) + { + DDPipeClient _client = new DDPipeClient(); + _client.Send(message, GetIPCPipeName()); + } + + private static string GetIPCPipeName() + { + return Application.ProductName + "." + Environment.UserName; } public void DialFromCommandlineArgs(string[] args) diff --git a/Fop2DD/Core/IPC/DDPipeClient.cs b/Fop2DD/Core/IPC/DDPipeClient.cs new file mode 100644 index 0000000..99bfeb2 --- /dev/null +++ b/Fop2DD/Core/IPC/DDPipeClient.cs @@ -0,0 +1,45 @@ +using System; +using System.IO.Pipes; +using System.Text; + +namespace Fop2DD.Core.IPC +{ + class DDPipeClient + { + public void Send(string value, string pipeName, int timeout = 1000) + { + try + { + NamedPipeClientStream pipestream = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.Asynchronous); + // The connect function will indefinitely wait for the pipe to become available + // If that is not acceptable specify a maximum waiting time (in ms) + pipestream.Connect(timeout); + byte[] _buffer = Encoding.UTF8.GetBytes(value); + pipestream.BeginWrite(_buffer, 0, _buffer.Length, new AsyncCallback(AsyncSend), pipestream); + } + catch + { + + } + } + + private void AsyncSend(IAsyncResult iar) + { + try + { + // Get the pipe + NamedPipeClientStream pipeStream = (NamedPipeClientStream)iar.AsyncState; + + // End the write + pipeStream.EndWrite(iar); + pipeStream.Flush(); + pipeStream.Close(); + pipeStream.Dispose(); + } + catch + { + + } + } + } +} diff --git a/Fop2DD/Core/IPC/DDPipeMessageReceivedEventArgs.cs b/Fop2DD/Core/IPC/DDPipeMessageReceivedEventArgs.cs new file mode 100644 index 0000000..57d3781 --- /dev/null +++ b/Fop2DD/Core/IPC/DDPipeMessageReceivedEventArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Fop2DD.Core.IPC +{ + public class DDPipeMessageReceivedEventArgs : EventArgs + { + public string Data { get; set; } + + public DDPipeMessageReceivedEventArgs(string data) + { + this.Data = data; + } + } +} diff --git a/Fop2DD/Core/IPC/DDPipeServer.cs b/Fop2DD/Core/IPC/DDPipeServer.cs new file mode 100644 index 0000000..afbc402 --- /dev/null +++ b/Fop2DD/Core/IPC/DDPipeServer.cs @@ -0,0 +1,70 @@ +using System; +using System.IO.Pipes; +using System.Text; + +namespace Fop2DD.Core.IPC +{ + public class DDPipeServer + { + public event MessageReceivedHandler MessageReceived; + public delegate void MessageReceivedHandler(object sender, DDPipeMessageReceivedEventArgs e); + + private string _pipename; + private const int BUFFERSIZE = 4096; + + public void Listen(string PipeName) + { + try + { + _pipename = PipeName; + // Create the new async pipe + NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, BUFFERSIZE, 0); + + // Wait for a connection + pipeServer.BeginWaitForConnection + (new AsyncCallback(WaitForConnectionCallBack), pipeServer); + } + catch + { + + } + } + + private void WaitForConnectionCallBack(IAsyncResult iar) + { + try + { + // Get the pipe + NamedPipeServerStream pipeserver = (NamedPipeServerStream)iar.AsyncState; + // End waiting for the connection + pipeserver.EndWaitForConnection(iar); + + byte[] buffer = new byte[BUFFERSIZE]; + + // Read the incoming message + var bytesread = pipeserver.Read(buffer, 0, buffer.Length); + + // Convert byte buffer to string + string data = Encoding.UTF8.GetString(buffer, 0, bytesread); + + // Pass message back to calling form + if (!string.IsNullOrEmpty(data) && (this.MessageReceived != null)) + MessageReceived(this, new DDPipeMessageReceivedEventArgs(data)); + + // Kill original sever and create new wait server + pipeserver.Close(); + pipeserver.Dispose(); + pipeserver = new NamedPipeServerStream(_pipename, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, BUFFERSIZE, BUFFERSIZE); + + // Recursively wait for the connection again and again.... + pipeserver.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), pipeserver); + } + catch + { + return; + } + } + } + + +} diff --git a/Fop2DD/Fop2DD.csproj b/Fop2DD/Fop2DD.csproj index 3884714..07446fc 100644 --- a/Fop2DD/Fop2DD.csproj +++ b/Fop2DD/Fop2DD.csproj @@ -72,6 +72,9 @@ + + + diff --git a/Fop2DD/Program.cs b/Fop2DD/Program.cs index 5f1a891..eefd961 100644 --- a/Fop2DD/Program.cs +++ b/Fop2DD/Program.cs @@ -1,4 +1,5 @@ using Fop2DD.Core; +using Fop2DD.Core.IPC; using Fop2DD.Core.Logging; using Newtonsoft.Json; using System; @@ -51,11 +52,8 @@ static void Main(string[] args) } else { - //There's already an instance running - - //TODO: We need to get the running instance to run _core.DialFromCommandlineArgs(args) on it - //OR - //TODO: We need to notify the running instance via IPC (tcp? named pipes? other...?) to run _core.DialFromCommandlineArgs(args) FOR us... + //There's already an instance running; pass along our commandline args + DDCore.SendIPCPessage(string.Join("|", args)); } } } diff --git a/Fop2DD/Properties/AssemblyInfo.cs b/Fop2DD/Properties/AssemblyInfo.cs index f6fd491..db7fdbe 100644 --- a/Fop2DD/Properties/AssemblyInfo.cs +++ b/Fop2DD/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.4.3.0")] -[assembly: AssemblyFileVersion("0.4.3.0")] +[assembly: AssemblyVersion("0.5.0.0")] +[assembly: AssemblyFileVersion("0.5.0.0")] diff --git a/Fop2DD/setup.iss b/Fop2DD/setup.iss index 1a02ded..a98035f 100644 --- a/Fop2DD/setup.iss +++ b/Fop2DD/setup.iss @@ -3,11 +3,11 @@ [Setup] AppPublisher=KeenSystems AppPublisherURL=http://www.keensystems.eu -AppVersion=0.4.3.0 +AppVersion=0.5.0.0 AppName=Fop2DD -AppVerName=Fop2DD 0.4.3 +AppVerName=Fop2DD 0.5.0 AppCopyright=Copyright (C) 2013 KeenSystems -VersionInfoVersion=0.4.3.0 +VersionInfoVersion=0.5.0.0 DefaultDirName={pf}\KeenSystems\Fop2DD DefaultGroupName=KeenSystems\Fop2DD UninstallDisplayIcon={app}\Fop2DD.exe