WinForms: Form.FromHandle возвращает значение null для главной формы процесса для кода, загруженного в исполняемый файл .net - PullRequest
1 голос
/ 12 ноября 2010

У меня есть устаревшее приложение, написанное на .Net. Нет доступных источников. Он использует скрипты vb для расширения внутренней логики посредством обработки событий. Так что это сочетание com и .net.

Я использовал приложение SpyUI и заметил, что интерфейс написан с помощью Windows Forms. Элементы управления названы в стиле .Net и похоже, что окна образуют единое целое (vc ++ и vb UI выглядят совершенно по-разному).

Я хочу расширить пользовательский интерфейс приложения, получив экземпляр System.Windows.Forms.Form для основной формы и изменив дерево элементов управления.

Итак, я пишу код в vb script, который создает мой com-объект, что-то вроде:

Set obj = CreateObject("MyUiExtender")
obj.InjectIntoUi()

Я пытаюсь получить основной дескриптор формы для объекта процесса, в который загружен, и этот код работает:

Process.GetCurrentProcess().MainWindowHandle; // a meaningfull value
Process.GetCurrentProcess().MainWindowTitle; // the title of the application 

Пока все хорошо, но следующее не работает -> возвращает ноль

var mainForm = Control.FromHandle(Process.GetCurrentProcess().MainWindowHandle)

Мой объект был загружен в исполняемый файл, и я пытаюсь получить экземпляр формы для того же процесса. Я полагаю, это своего рода проблема с границами приложения. Мой код работает отлично, если мой com-объект загружается в приложение .net через

t = Type.GetTypeFromProgID("MyUiExtender")
dynamic c = Activator.CreateInstance(t)
c.InjectIntoUi();

Полагаю, использование сценариев vb как-то разрушает границы приложений ...

Возможно ли получить экземпляр основной формы приложения как экземпляр класса Windows.Forms.Form?

1 Ответ

1 голос
/ 09 июня 2011

Проблема в том, что Control.FromHandle работает только для текущего процесса. Если вы хотите получить основную форму другого процесса .Net, вам нужно внедрить свой код в другой процесс.

Есть несколько подходов к этому. Наиболее распространенным является использование CreateRemoteThread для загрузки неуправляемой DLL в другое адресное пространство процесса, а затем загрузка сборки .NET. Чтобы сделать это возможным, вы должны использовать управляемый C ++.

Если вы новичок, я бы порекомендовал использовать существующую библиотеку. Посмотрите на проект Hawkeye на CodePlex: http://hawkeye.codeplex.com/ Вы можете найти готовую библиотеку там.

Вы также можете взглянуть на http://smuxplugins.codeplex.com/ Это еще один пример внедрения кода .net.

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