Запустите приложение winform из службы Windows - PullRequest
1 голос
/ 26 августа 2010

Пожалуйста, дайте мне знать, как мне запустить приложение под текущим вошедшим в систему пользователем из службы.

Для справки, у меня есть служба Windows VB.NET, единственная функциональность которой заключается в запуске приложения Winform.в указанное время.Кроме того, он также устанавливает системный таймер пробуждения, чтобы система могла быть активирована в указанное время, если она переходит в режим ожидания / сна, чтобы запустить приложение.Этот сервис должен обслуживать рабочие столы XP / Vista / Win7 в нашей сети.Этот сервис не будет работать на серверах и ноутбуках.

Приложение Winform показывает пользовательский интерфейс для предоставления некоторых входных данных.Если пользователь не вводит данные в течение 15 минут, он по умолчанию принимает значение и затем переходит в значок на панели задач.Пользователь может щелкнуть значок и изменить значения позже (в течение определенного периода времени, и это тоже только дважды).

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

Если пользователь не вошел в систему, я также хочу, чтобы приложение запускалось в указанное время.Как я уже говорил, у приложения есть таймер по умолчанию.Так что, если какой-то пользователь только что вышел из системы, то приложение winform установит значения по умолчанию.

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

В настоящее время, когда я запускаю app.exe через process.start () внутри службы, он запускается под учетной записью SYSTEM, так как служба также запущена.в локальной системе.Так что в основном я не получаю никакого интерфейса.Есть ли способ запустить его под текущим вошедшим пользователем?Я не беспокоюсь о многопользовательском входе в систему, поскольку мы не будем запускать его на серверах, а переключение пользователей не включено на наших рабочих столах.Даже если кто-то сделал удаленный вход в систему через mstsc, мне также нужно запустить приложение и показать пользовательский интерфейс.

Пожалуйста, дайте мне знать, как запустить приложение под текущим зарегистрированным пользователем изсервис.

Спасибо, аскиды

1 Ответ

1 голос
/ 28 августа 2010

Были некоторые дополнительные комментарии, которые я отправил. Но я как-то не вижу этого: (

Возвращаясь к первоначальному вопросу. Я смог понять это после нескольких проб и ошибок. Я подробно изложу.

В Vista и выше службы работают изолированно от других пользовательских сессий. Они запускаются в сеансе 0. Сеансы пользователей выполняются в 1 и выше. Так что в основном вам нужно эмулировать процесс как текущий вошедший в систему пользователь.

  1. Использовать WTSEnumerateSessions и получить сессий. Проверьте, если сессия состояние активно. Это будет текущий пользователь вошел в сеанс. Если нет активных сессий, это означает, что пользователь не вошел в систему. В мой случай, будет только 1 зарегистрирован на пользователя. Так что мне не нужно выяснять, активный сеанс (как и другие могут нужно сделать).
  2. Используйте WTSQueryUserToken , чтобы получить токен пользователя в активном сеансе. Создайте основной токен пользователя, используя DuplicateTokenEx
  3. Создание среды с использованием CreateEnvironmentBlock
  4. Используйте информацию выше в CreateProcessAsUser

Причина, по которой он работал в XP, а не в Vista, заключалась в том, что, похоже, информация по умолчанию при запуске отличается. После того, как я установил флаг wShowWindow структуры startupinfo, GUI начал бы появляться.

Dim StartupInfo As New STARTUPINFO()
StartupInfo.cb = Marshal.SizeOf(StartupInfo)
StartupInfo.dwFlags = STARTF_USESHOWWINDOW 
StartupInfo.wShowWindow = WINDOW_STATUS.SW_SHOWNORMAL

Еще одна дополнительная информация. Я пытался установить рабочий стол по умолчанию, используя
StartupInfo.lpDesktop = "WinSta0\\Default"
из-за чего приложение вылетает при запуске. Поэтому я закомментировал это.

У меня все еще есть последний вопрос. Запущенное приложение не в фокусе. GUI появляется, но в фоновом режиме. Но я думаю, это снова будет связано с некоторыми параметрами, как указано выше. Как только я это выясню, я добавлю детали.

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