Получить ссылку на UserControl из другого домена приложения (составной пользовательский интерфейс)

Как я могу разместить WinForms Control (или WPF Window, если уж на то пошло), созданный в другом AppDomain, в форме, созданной в моем приложении?

Я пытаюсь создать составное приложение пользовательского интерфейса, которое представляет собой безфункциональную оболочку/хост для плагинов, где эти плагины работают полностью в своих собственных доменах приложений, поэтому я хочу иметь возможность получать объекты UserControl из этих плагинов для «размещения» в какой-то элемент управления контейнером в основной форме хост-процесса.

Я думал, что взломал его, но поскольку диалоги между доменами приложений включают прокси-серверы MarshallByRefObject, я не могу использовать свой первый подход к прототипу:

shellForm.Panel1.Controls.Add(proxyObjectForUserControlInOtherAssembly);

Я разместил исключение, которое я получил от этого, в конце вопроса.

Я пытался получить управление напрямую:

var ctl = Control.FromHandle(proxyObjectForUserControlInOtherAssembly.Handle);
shellForm.Panel1.Controls.Add(ctl);

Это дало предсказуемые результаты. Я получил hWnd в порядке, но Control.FromHandle() вернул null. Предположительно, потому что дескриптор был создан в другом домене приложения.

Я был бы очень признателен за то, что тыкаешь в правильном направлении, если я безнадежно сбился с пути. :)

Спасибо заранее.


System.Runtime.Remoting.RemotingException was unhandled by user code
  Message=Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.
  Source=mscorlib
  StackTrace:
       at System.Object.GetFieldInfo(String typeName, String fieldName)
       at System.Object.FieldGetter(String typeName, String fieldName, Object& val)
       at System.Object.FieldGetter(String typeName, String fieldName, Object& val)
       at System.Windows.Forms.Control.ControlCollection.Add(Control value)
       at AppDomainTest.Shell.Form1.Display(Control control) in c:\temp\AppDomainTest\AppDomainTest\AppDomainTest.Shell\Form1.cs:line 24
       at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
       at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
  InnerException: 

person Neil Barnwell    schedule 06.04.2011    source источник


Ответы (1)


Мне коллега услужливо указал на одно возможное направление: .NET Add-in Framework

Ключевой момент с этой страницы для моих целей заключается в следующем:

Сборки для этих сегментов не обязательно должны находиться в одном и том же домене приложения. Вы можете загрузить надстройку в собственный новый домен приложения, в существующий домен приложения или даже в домен приложения хоста. Вы можете загружать несколько надстроек в один и тот же домен приложения, что позволяет надстройкам совместно использовать ресурсы и контексты безопасности.

person Neil Barnwell    schedule 06.04.2011
comment
Привет, Нил. Вы в конечном итоге использовали платформу .Net AddIn? Из того, что вы прочитали, можно размещать окна WPF, созданные в другом AppDomain (WPF поставляется с уже реализованными адаптерами для этого), но это невозможно для Windows Forms. Вы пытались создать свои собственные адаптеры для передачи элементов управления WinForms? - person Aoi Karasu; 26.01.2014