我有两个程序集,我试图将它们链接在一起。
- 一种是使用 WinForms 构建的一种后台进程,旨在作为 Windows 服务运行。
- 我有第二个项目,每当用户启动它时,它将充当后台进程的 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 编组回字符串时,我得到一个空字符串。我使用的堆区域是否超出了其他进程的范围,或者我是否缺少某些安全属性?有没有更好、更干净的方法来使用事件驱动模型来处理这样的事情?