Re[2]: Передача объекта между приложениями
От: Woonder  
Дата: 16.10.08 06:39
Оценка:
Здравствуйте, Pavel M., Вы писали:

PM>Здравствуйте, Woonder, Вы писали:



W>>Спасибо.


PM>Задача определения того, есть ли уже запущенное приложение данное, решается с помощью Mutex! Передача данных приведенными выше способами. SendMessage работает если у приложежния есть главное окно, вроде.


Определить, есть ли запущенное приложение — я могу, а вот с передачей сообщения были проблемы...
Я использовал не SendMessage, a PostThreadMessage так как нужно было передать сообщение не окну, а главному потоку другого приложения. И сам факт передачи и приема сообщения есть, но только вот данных в lParam и wParam нету. Вот часть кода:


public class MessagesHelper
{
    public static T ExtractData<T>(IntPtr wParam, IntPtr lParam)
    {
        IntPtr lengthPtr = lParam;
        int length = Marshal.ReadInt32(lengthPtr);
        byte[] receivedBytes = new byte[length];
        IntPtr bytesPtr = wParam;

        Marshal.Copy(bytesPtr, receivedBytes, 0, length);

        BinaryFormatter serializer = new BinaryFormatter();
        using (MemoryStream inputStream = new MemoryStream(receivedBytes, false))
        {
            return (T) serializer.Deserialize(inputStream);
        }
    }


    [DllImport("user32.dll", EntryPoint="GetMessage", CharSet=CharSet.Auto)]
    public static extern int NativeGetMessage(out NativeMessage msg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);


    [DllImport("user32.dll", EntryPoint="PeekMessage", CharSet=CharSet.Auto)]
    public static extern bool NativePeekMessage(out NativeMessage msg, IntPtr senderHandle, KnownMessages msgMin, KnownMessages msgMax, PeekAction action);


    [DllImport("user32.dll", EntryPoint="PostThreadMessage", CharSet=CharSet.Auto)]
    public static extern bool NativePostThreadMessage(int threadId, KnownMessages message, IntPtr wParam, IntPtr lParam);


    [DllImport("user32.dll", EntryPoint="PostMessage", CharSet=CharSet.Auto)]
    public static extern int NativePostWindowMessage(IntPtr handle, int message, IntPtr wParam, IntPtr lParam);


    public static UserMessage PopUserMessage(IntPtr senderHandle)
    {
        NativeMessage nativeMessage;

        if (NativePeekMessage(out nativeMessage, senderHandle, KnownMessages.WmUser, KnownMessages.WmUser, PeekAction.Remove))
        {
            return new UserMessage(nativeMessage);
        }

        return null;
    }


    public static bool PostUserMessageToThread(int threadId, object data)
    {
        byte[] sendingBytes;
        BinaryFormatter serializer = new BinaryFormatter();

        using (MemoryStream outputStream = new MemoryStream())
        {
            serializer.Serialize(outputStream, data);
            sendingBytes = outputStream.ToArray();
        }

        IntPtr unmanagedDataPtr = Marshal.AllocHGlobal(sendingBytes.Length);

        Marshal.Copy(sendingBytes, 0, unmanagedDataPtr, sendingBytes.Length);

        IntPtr lengthPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));

        Marshal.WriteInt32(lengthPtr, sendingBytes.Length);

        return NativePostThreadMessage(threadId, KnownMessages.WmUser, unmanagedDataPtr, lengthPtr);
    }


    public enum PeekAction
    {
        NoRemove,
        Remove,
        NoYield
    }
}


/////////////////////////////////////////////////////////////////////////////////////

public class UserMessage : IDisposable
{
    private object data;
    private NativeMessage nativeMessage;


    internal UserMessage(NativeMessage message)
    {
        this.nativeMessage = message;
    }


    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }


    protected virtual void Dispose(bool disposing)
    {
        if (this.nativeMessage != NativeMessage.Empty)
        {
            this.nativeMessage.Dispose();
            this.nativeMessage = NativeMessage.Empty;
        }
    }


    public object ExtractObject()
    {
        return this.ExtractObject(new ObjectExtractor(MessagesHelper.ExtractData<object>));
    }


    public object ExtractObject(ObjectExtractor extractor)
    {
        if (this.data == null)
        {
            this.data = extractor(this.nativeMessage.wParam, this.nativeMessage.lParam);
        }
        return this.data;
    }


    ~UserMessage()
    {
        this.Dispose(false);
    }


    public Point CursorPosition
    {
        get
        {
            return this.nativeMessage.CursorCoords;
        }
    }


    public IntPtr DestinationWindowHandle
    {
        get
        {
            return this.nativeMessage.DestinationWindowHandle;
        }
    }


    public DateTime Time
    {
        get
        {
            return DateTime.FromBinary((long) this.nativeMessage.time);
        }
    }
}




При приеме сообщения указатель lParam (который в моем случае указывает на длину байт массива который должен быть в wParam) равен нулю.
И некоторые пишут, что так и должно быть... здесь
Автор: _Mihail
Дата: 02.01.08


Если так и должно быть, то прийдется юзать remoting, pipes или еще что-то.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.