// ------------------------------------------------------------------------------------ /// <summary> /// Send message to Snarl. /// Will UTF8 encode the message before sending. /// </summary> /// <param name="request">The Snarl request key/value pair strings.</param> /// <param name="replyTimeout">Timeout before returning an error if Snarl is too slow to respond.</param> /// <returns>Return zero or positive on success. Negative on error.</returns> public static Int32 DoRequest(String request, UInt32 replyTimeout = 1000) { Int32 nReturn = -1; IntPtr nSendMessageResult = IntPtr.Zero; IntPtr ptrToUtf8Request = IntPtr.Zero; IntPtr ptrToCds = IntPtr.Zero; byte[] utf8Request = null; // Test if Snarl is running IntPtr hWnd = GetSnarlWindow(); if (!NativeMethods.IsWindow(hWnd)) return -(int)SnarlStatus.ErrorNotRunning; try { // Convert to UTF8 UTF8Encoding utf8 = new UTF8Encoding(); utf8Request = new byte[utf8.GetMaxByteCount(request.Length)]; int convertCount = utf8.GetBytes(request, 0, request.Length, utf8Request, 0); // Create interop struct var cds = new NativeMethods.COPYDATASTRUCT(); cds.dwData = (IntPtr)0x534E4C03; // "SNL",3 cds.cbData = convertCount; // Create unmanaged byte[] and copy utf8Request into it ptrToUtf8Request = Marshal.AllocHGlobal(convertCount); Marshal.Copy(utf8Request, 0, ptrToUtf8Request, convertCount); cds.lpData = ptrToUtf8Request; // Create unmanaged pointer to COPYDATASTRUCT ptrToCds = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NativeMethods.COPYDATASTRUCT))); Marshal.StructureToPtr(cds, ptrToCds, false); if (NativeMethods.SendMessageTimeout(hWnd, (uint)WindowsMessage.WM_COPYDATA, (IntPtr)NativeMethods.GetCurrentProcessId(), ptrToCds, NativeMethods.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG | NativeMethods.SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG, replyTimeout, out nSendMessageResult) == IntPtr.Zero) { // Error int nError = Marshal.GetLastWin32Error(); if (nError == NativeMethods.ERROR_TIMEOUT) nReturn = -(Int32)SnarlStatus.ErrorTimedOut; else nReturn = -(Int32)SnarlStatus.ErrorFailed; } else { // SendMessage success nReturn = unchecked((Int32)nSendMessageResult.ToInt64()); // Avoid arithmetic overflow error } } finally { utf8Request = null; Marshal.FreeHGlobal(ptrToCds); Marshal.FreeHGlobal(ptrToUtf8Request); } return nReturn; }
//send a notification to the already existing instance that a new instance was started private bool NotifyPreviousInstance(object message) { //First, find the window of the previous instance IntPtr handle = NativeMethods.FindWindow(null, _id); if (handle != IntPtr.Zero) { //create a GCHandle to hold the serialized object. GCHandle bufferHandle = new GCHandle(); try { byte[] buffer; NativeMethods.COPYDATASTRUCT data = new NativeMethods.COPYDATASTRUCT(); if (message != null) { //serialize the object into a byte array buffer = Serialize(message); //pin the byte array in memory bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); data.dwData = 0; data.cbData = buffer.Length; //get the address of the pinned buffer data.lpData = bufferHandle.AddrOfPinnedObject(); } GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { NativeMethods.SendMessage(handle, NativeMethods.WM_COPYDATA, IntPtr.Zero, dataHandle.AddrOfPinnedObject()); return true; } finally { dataHandle.Free(); } } finally { if (bufferHandle.IsAllocated) bufferHandle.Free(); } } return false; }
private bool NotifyPreviousInstance(object message) { IntPtr handle = NativeMethods.FindWindow(null, _id); if (handle != IntPtr.Zero) { GCHandle bufferHandle = new GCHandle(); try { NativeMethods.COPYDATASTRUCT data = new NativeMethods.COPYDATASTRUCT(); if (message != null) { byte[] buffer = Serialize(message); bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); data.dwData = 0; data.cbData = buffer.Length; data.lpData = bufferHandle.AddrOfPinnedObject(); } GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { NativeMethods.SendMessage(handle, NativeMethods.WM_COPYDATA, IntPtr.Zero, dataHandle.AddrOfPinnedObject()); return true; } finally { dataHandle.Free(); } } finally { if (bufferHandle.IsAllocated) bufferHandle.Free(); } } return false; }