Как я могу получить MainWindowHandle приложения Windows 7, работающего от имени пользователя ‹foo›, из службы, работающей от имени локальной системы?

Я создал службу, которая работает как пользователь локальной системы. Эта служба запускает и отслеживает приложение Silverlight вне браузера, используя собственное взаимодействие и метод CreateProcessAsUser() (чтобы запустить его от имени вошедшего в данный момент пользователя, а не от локальной системы). Я могу получить дескриптор порожденного процесса и выполнять такие действия, как Kill(), однако мне стало известно, что служба не может получить дескриптор главного окна дочернего приложения, потому что дочернее приложение работает под другим пользователем. Я работаю на Windows 7.

Моя конечная цель - правильно реагировать на то, когда процесс перестает отвечать (т.е. Process.Responding == false), чтобы я мог убить приложение и перезапустить его. Однако для Process.Responding требуется дескриптор главного окна процесса (точнее, Process.MainWindowHandle), однако в этом сценарии Process.MainWindowHandle всегда возвращает 0.

Я в тупике здесь. Есть ли способ для одного пользователя получить дескриптор окна для процесса, работающего от имени другого пользователя в Win 7?

Заранее спасибо за любую помощь.


person Darren David    schedule 18.04.2011    source источник


Ответы (1)


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

Более подробная информация доступна здесь:

Строго говоря, то, для чего вы используете службу Windows в первую очередь, — это плохой дизайн. Он не должен создавать или запускать какие-либо процессы пользовательского режима или каким-либо образом взаимодействовать с пользователем. Помните, что службы работают, даже если ни один пользователь не вошёл в систему! Таким образом, они не должны запускать приложения.

Лучшим решением является простое фоновое приложение, настроенное на автоматический запуск при входе пользователя в систему. Затем это фоновое приложение может запускать приложение Silverlight, отслеживать его состояние и при необходимости взаимодействовать с ним, поскольку оба приложения будут работать в контексте та же локальная учетная запись пользователя. Эффект аналогичен услуге, но без каких-либо недостатков изоляции. Самый простой способ сделать это в Visual Studio — создать приложение WinForms (или, возможно, приложение WPF, у меня меньше опыта в этой области), которое просто не отображает никаких форм/окон.

person Cody Gray    schedule 18.04.2011