У меня есть две сборки, которые я пытаюсь связать вместе.
- Один из них - это своего рода фоновый процесс, который построен с помощью WinForms и предназначен для работы в качестве службы Windows.
- У меня есть второй проект, который будет выступать в качестве пользовательского интерфейса для фонового процесса всякий раз, когда пользователь запускает его.
Я никогда раньше не пытался делать что-то подобное с управляемым кодом, поэтому я начал пытаться использовать сообщения Windows для связи между двумя процессами. Однако я испытываю трудности, когда дело доходит до передачи большего, чем просто IntPtrs.
Вот код из элемента управления в моем проекте пользовательского интерфейса, который регистрируется в фоновом процессе:
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);
}
Это код из фонового процесса, который должен получать запрос от процесса пользовательского интерфейса для регистрации обновлений статуса и отправки подтверждающего сообщения.
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);
}
Процесс пользовательского интерфейса получает сообщение INIT_CONFIRMED
от моего фонового процесса, но когда я пытаюсь собрать IntPtr обратно в строку, я получаю пустую строку. Область кучи, которую я использую, выходит за рамки другого процесса, или мне не хватает какого-либо атрибута безопасности? Есть ли лучший и более чистый способ сделать что-то подобное с использованием модели, управляемой событиями?