У меня есть две сборки, которые я пытаюсь связать.Как передать управляемые объекты из одного процесса в другой?
- Один из видов фонового процесса, созданного с помощью WinForms, и предназначен для работы в качестве службы Windows.
- У меня есть второй проект, который будет действовать как пользовательский интерфейс для фонового процесса всякий раз, когда пользователь запускает его.
Я никогда не пытался попробовать что-то вроде этого с управляемым кодом раньше, поэтому я начал пытаться использовать сообщения 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);
}
Это код от фонового процесса, который, как предполагается, получит запрос от процесса пользовательского интерфейса для регистрации для обновить статус и отправить подтверждение.
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 обратно в строку, я получаю пустую строку. Является ли область кучи, которую я использую вне сферы действия для другого процесса, или мне не хватает какого-либо атрибута безопасности? Есть ли лучший и более чистый способ сделать что-то подобное с помощью модели, управляемой событиями?
Так это AppDomain для AppDomain или процесса для обработки? - большая разница. Звучит так, как будто вы хотите Process-Process, и поэтому вы можете исправить вопрос. –
О да, моя ошибка. Моя первая попытка заключалась в использовании GCHandles, и она создала исключение с сообщением о том, что GCHandle не может использоваться вне AppDomain, но это определенно проблема процесса для процесса. –