如何将托管对象从一个进程传递到另一个进程?

时间:2010-05-04 22:56:24

标签: c# windows marshalling managed unmarshalling

我有两个组件正在尝试链接在一起。

  1. 一种是使用WinForms构建的后台进程,它将被设计为作为Windows服务运行。
  2. 我有第二个项目,只要用户启动它,它就会充当后台进程的UI。
  3. 我之前从未尝试使用托管代码尝试此类内容,因此我开始尝试使用Windows消息在两个进程之间进行通信。然而,当涉及到来回传递的不仅仅是IntPtrs时,我正在努力。

    这是我的UI项目中的控件的代码,它使用后台进程注册自己:

    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);
    }
    

    这是后台进程中的代码,它应该从UI进程接收请求以注册状态更新并发送确认消息。

     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);
    }
    

    UI进程从我的后台进程接收INIT_CONFIRMED消息,但是当我尝试将IntPtr封送回字符串时,我得到一个空字符串。我使用的堆区域是否超出了其他进程的范围,或者我错过了一些安全属性?有没有更好更清洁的方法来使用事件驱动模型来做这样的事情?

1 个答案:

答案 0 :(得分:1)

不确定是否要使用此路由,但您可能更容易将WCF用作IPC层,而不是使用低级Windows IPC。您需要为服务构建和公开接口,然后使用UI应用程序连接到它们。

如果你想尝试一下,有很多很好的WCF教程。