How can I pass managed objects from one AppDomain to another?

Posted by Dennis P on Stack Overflow See other posts from Stack Overflow or by Dennis P
Published on 2010-05-04T22:56:24Z Indexed on 2010/05/04 22:58 UTC
Read the original article Hit count: 281

I have two assemblies that I'm trying to link together. One is a sort of background process that's built with WinForms and will be designed to run as a Windows Service. I have a second project that will act as a UI for the background process whenever a user launches it. I've never tried attempting something like this with managed code before, so I've started trying to use windows messages to communicate between the two processes. I'm struggling when it comes to passing more than just IntPtrs back and forth, however.

Here's the code from a control in my UI project that registers itself with the background process:

public void Init()
    {
        IntPtr hwnd = IntPtr.Zero;
        Process[] ps = Process.GetProcessesByName("BGServiceApp");
        Process mainProcess = null;
        if(ps == null || ps.GetLength(0) == 0)
        {
            mainProcess = LaunchApp();
        }
        else
        {
            mainProcess = ps[0];
        }
        SendMessage(mainProcess.MainWindowHandle, INIT_CONNECTION, this.Handle, IntPtr.Zero);
    } 
protected override void  WndProc(ref Message m)
    {
        if(m.Msg == INIT_CONFIRMED && InitComplete != null)
        {
            string message = Marshal.PtrToStringAuto(m.WParam);
            Marshal.FreeHGlobal(m.WParam);

            InitComplete(message, EventArgs.Empty);

        }
        base.WndProc(ref m);
    }

This is the code from the background process that's supposed to receive a request from the UI process to register for status updates and send a confirmation message.

 protected override void WndProc(ref Message m)
    {

        if(m.Msg == INIT_CONNECTION)
        {
            RegisterUIDispatcher(m.WParam);
            Respond(m.WParam);
        }

        if(m.Msg == UNINIT_CONNECTION)
        {
            UnregisterUIDispatcher(m.WParam);
            if(m_RegisteredDispatchers.Count == 0)
            {
                this.Close();
            }
        }
        base.WndProc(ref m);
    }

    private void Respond(IntPtr caller)
    {
        string test = "Registration confirmed!";
        IntPtr ptr = Marshal.StringToHGlobalAuto(test);

        SendMessage(caller, INIT_CONFIRMED, ptr, IntPtr.Zero);
        }
    }

The UI process receives the INIT_CONFIRMED message from my background process, but when I try to marshal the IntPtr back into a string, I get an empty string. Is the area of heap I'm using out of scope to the other process or am I missing some security attribute maybe? Is there a better and cleaner way to go about something like this using an event driven model?

© Stack Overflow or respective owner

Related posts about Windows

Related posts about c#