Использование SetParent для кражи главного окна другого процесса, но с разделением циклов сообщений - PullRequest
3 голосов
/ 04 марта 2011

Предыстория: мой коллега и я поддерживаем унаследованное приложение, состоящее из миллиона строк. Его интерфейс написан на VB6, и, поскольку мы почти все наши ресурсы посвящаем его преобразованию в C #, мы ищем быстрые и грязные решения нашей конкретной проблемы.

Приложение работает в режиме плагина. Существует до 20 отдельных элементов управления ActiveX, которые можно загрузить сразу в виде сетки. Проблема состоит в том, что элементы управления ActiveX выполняют всю свою обработку в своем собственном потоке пользовательского интерфейса, и, поскольку большая часть его блокирует ожидание при доступе к сети, пользовательский интерфейс становится очень сложным. Когда наше управляющее приложение C # загружает эти элементы управления, оно перестает отвечать из-за того, что многие элементы управления поглощают ресурсы пользовательского интерфейса и ничего не делают. В довершение всего, элементы управления хрупки и будут падать при малейшей провокации. Когда они размещаются в основном приложении C #, это создает серьезную нестабильность.

Лучшее, что мы с коллегой придумали, - это запуск процесса для элемента управления ActiveX. Этот процесс, который мы называем прокси, является еще одним приложением winforms. Он использует именованные каналы для связи с процессом хостинга. Процесс хостинга создает окно, загружает элемент управления ActiveX по нашему выбору (через некоторые отражения и магию AxHost) и сообщает основному процессу, что его дескриптор окна использует через именованный канал. Основной процесс использует комбинацию SetParent и SetWindowPos для перемещения прокси-приложения в себя, чтобы эмулировать плагин. Обновления размера отправляются через именованный канал.

Это работает достаточно хорошо, пока приложение ActiveX не выполняет какой-то длительный процесс, и мы не нажимаем на главное окно, пока оно работает. Какое-то время главное окно реагирует, но в конечном итоге оно перестает отвечать, поскольку дочернее окно ожидает своего потока пользовательского интерфейса. Как мы можем сохранить дочерние окна в их собственном полном потоке, все еще получая преимущества SetParent?

(пожалуйста, дайте мне знать, если что-то не понятно!)

1 Ответ

5 голосов
/ 04 марта 2011

Я делал это раньше.Это становится грязным.

Мы запускали каждый плагин в своем собственном домене приложений, который запускал собственный поток пользовательского интерфейса.Мы сделали это после того, как столкнулись с множеством действительно неприятных проблем, когда мы не не использовали разные потоки пользовательского интерфейса.

Это означает, что вы испытываете все трудности при общении через домены приложений, но это выполнимо,Главное, что вам нужно будет запустить Application.Run в каждом домене приложений / плагине.Общайтесь с ними с огромным вниманием - даже сложно отключиться.

Удачи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...