/// <summary> /// Sends the specified object on this channel to any other /// applications which are listening. The object must have the /// SerializableAttribute set, or must implement ISerializable. /// </summary> /// <param name="obj">The object to send</param> /// <returns>The number of recipients</returns> public int Send(object obj) { int recipients = 0; if (disposed) { throw new InvalidOperationException("Object has been disposed"); } if (recreateChannel) // handle has changed { addChannel(); } CopyDataObjectData cdo = new CopyDataObjectData(obj, channelName); // Try to do a binary serialization on obj. // This will throw and exception if the object to // be passed isn't serializable. BinaryFormatter b = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); b.Serialize(stream, cdo); stream.Flush(); // Now move the data into a pointer so we can send // it using WM_COPYDATA: // Get the length of the data: int dataSize = (int)stream.Length; if (dataSize > 0) { // This isn't very efficient if your data is very large. // First we copy to a byte array, then copy to a CoTask // Mem object... And when we use WM_COPYDATA windows will // make yet another copy! But if you're talking about 4K // or less of data then it doesn't really matter. byte[] data = new byte[dataSize]; stream.Seek(0, SeekOrigin.Begin); stream.Read(data, 0, dataSize); IntPtr ptrData = Marshal.AllocCoTaskMem(dataSize); Marshal.Copy(data, 0, ptrData, dataSize); // Enumerate all windows which have the // channel name, send the data to each one EnumWindows ew = new EnumWindows(); ew.GetWindows(); // Send the data to each window identified on // the channel: foreach (EnumWindowsItem window in ew.Items) { if (!window.Handle.Equals(this.owner.Handle)) { if (GetProp(window.Handle, this.channelName) != 0) { COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.cbData = dataSize; cds.dwData = IntPtr.Zero; cds.lpData = ptrData; int res = SendMessage(window.Handle, WM_COPYDATA, (int)owner.Handle, ref cds); recipients += (Marshal.GetLastWin32Error() == 0 ? 1 : 0); } } } // Clear up the data: Marshal.FreeCoTaskMem(ptrData); } stream.Close(); return(recipients); }
/** * Initializes the IPC data exchange */ public void InitializeIPConnection(string[] args) { dataExchange = new CopyData(); dataExchange.AssignHandle(this.Handle); dataExchange.Channels.Add("FileOpen"); dataExchange.Channels.Add("ExitApplication"); dataExchange.DataReceived += new DataReceivedEventHandler(DataExchangeReception); if (!settings.HasKey("FlashDevelop.SingleInstance")) settings.AddValue("FlashDevelop.SingleInstance", "true"); if (settings.GetBool("FlashDevelop.SingleInstance")) { EnumWindows ew = new EnumWindows(); ew.GetWindows(); foreach(EnumWindowsItem ewi in ew.Items) { if (ewi.Text.EndsWith("- FlashDevelop")) { ewi.Restore(); dataExchange.Channels["FileOpen"].Send(args); throw new Exception("ExitApplication"); } } } }
/// <summary> /// Sends the specified object on this channel to any other /// applications which are listening. The object must have the /// SerializableAttribute set, or must implement ISerializable. /// </summary> /// <param name="obj">The object to send</param> /// <returns>The number of recipients</returns> public int Send(object obj) { int recipients = 0; if (disposed) { throw new InvalidOperationException("Object has been disposed"); } if (recreateChannel) // handle has changed { addChannel(); } CopyDataObjectData cdo = new CopyDataObjectData(obj, channelName); // Try to do a binary serialization on obj. // This will throw and exception if the object to // be passed isn't serializable. BinaryFormatter b = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); b.Serialize(stream, cdo); stream.Flush(); // Now move the data into a pointer so we can send // it using WM_COPYDATA: // Get the length of the data: int dataSize = (int)stream.Length; if (dataSize > 0) { // This isn't very efficient if your data is very large. // First we copy to a byte array, then copy to a CoTask // Mem object... And when we use WM_COPYDATA windows will // make yet another copy! But if you're talking about 4K // or less of data then it doesn't really matter. byte[] data = new byte[dataSize]; stream.Seek(0, SeekOrigin.Begin); stream.Read(data, 0, dataSize); IntPtr ptrData = Marshal.AllocCoTaskMem(dataSize); Marshal.Copy(data, 0, ptrData, dataSize); // Enumerate all windows which have the // channel name, send the data to each one EnumWindows ew = new EnumWindows(); ew.GetWindows(); // Send the data to each window identified on // the channel: foreach(EnumWindowsItem window in ew.Items) { if (!window.Handle.Equals(this.owner.Handle)) { if (GetProp(window.Handle, this.channelName) != 0) { COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.cbData = dataSize; cds.dwData = IntPtr.Zero; cds.lpData = ptrData; int res = SendMessage(window.Handle, WM_COPYDATA, (int)owner.Handle, ref cds); recipients += (Marshal.GetLastWin32Error() == 0 ? 1 : 0); } } } // Clear up the data: Marshal.FreeCoTaskMem(ptrData); } stream.Close(); return recipients; }