protected IntPtr WindowMessageHook(
            int msg,
            IntPtr wParam,
            IntPtr lParam,
            ref bool handled
            )
        {
            handled = false;

            if (msg != NativeMethods.WM_COPYDATA)
            {
                return(IntPtr.Zero);
            }

            MessageEnvelope envelope = EnvelopeCopyDataStruct.TryUnmarshalEnvelope(lParam);

            if (envelope != null && envelope.SharedIdentifier == SharedIdentifier)
            {
                InvokeMessageHandlers(envelope.Message);
                handled = true;
                return(CopyDataResultSuccess);
            }

            return(IntPtr.Zero);
        }
        private bool SendMessage(IntPtr targetWindowHandle, object message)
        {
            var envelope = new MessageEnvelope(SharedIdentifier, message);

            using (EnvelopeCopyDataStruct cds = new EnvelopeCopyDataStruct(envelope)) {
                IntPtr result;
                NativeMethods.SendMessageTimeout(
                    hWnd: targetWindowHandle,
                    Msg: NativeMethods.WM_COPYDATA,
                    wParam: IntPtr.Zero,
                    lParam: cds.Pointer,
                    fuFlags: SendMessageTimeoutFlags.SMTO_BLOCK | SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
                    uTimeout: 10000,
                    lpdwResult: out result
                    );

                return(result == CopyDataResultSuccess);
            }
        }