0

我有两个程序集,我试图将它们链接在一起。

  1. 一种是使用 WinForms 构建的一种后台进程,旨在作为 Windows 服务运行。
  2. 我有第二个项目,每当用户启动它时,它将充当后台进程的 UI。

我以前从未尝试过使用托管代码尝试这样的事情,所以我开始尝试使用 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 编组回字符串时,我得到一个空字符串。我使用的堆区域是否超出了其他进程的范围,或者我是否缺少某些安全属性?有没有更好、更干净的方法来使用事件驱动模型来处理这样的事情?

4

1 回答 1

1

不确定你是否想走这条路,但你可能会更容易使用 WCF 作为 IPC 层,而不是低级别的 Windows IPC 东西。您需要为服务构建和公开接口,然后使用您的 UI 应用程序连接到它们。

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

于 2010-05-04T23:01:27.097 回答