Я использую стороннюю службу Windows, которая обрабатывает некоторые задачи автоматизации, запуская скрипты и исполняемые файлы с помощью CreateProcessAsUser(). Я столкнулся с проблемами в Windows Server 2008 из-за UAC, и как возвышение LUA обрабатывается через API.
Служба работает как LocalSystem и не имеет "Interact With Desktop". Эти процессы запускаются как пользователи в группе "Администраторы", но не в учетной записи "Администратор" (которая освобождается от многих ограничений UAC). Все настройки UAC по умолчанию.
Я могу передать произвольные команды или код powershell службе, но я не могу "вырваться" из невысокого, неинтерактивного процесса, который запускается службой.
Суть проблемы заключается в том, что единственным (общедоступным) API-интерфейсом для запуска повышенного процесса является ShellExecute() с глаголом "runas", но насколько я могу сказать, что нельзя вызывать из неинтерактивный сервис, или вы получаете такие ошибки, как "Для этой операции требуется интерактивная оконная станция".
Единственное обходное решение, которое я нашел, упоминается здесь: http://www.eggheadcafe.com/software/aspnet/29620442/how-to-proper-use-sendinp.aspx
В Vista официальный документированный способ для подъема процесса используется только shell API ShellExecute (Ex) (не CreateProcess или CreateProcessAsUser). Поэтому ваше приложение должно ShellExecute (Ex) для запуска помощника для вызова SendInput. Кроме того, из-за Сессии 0 изоляции, услуга может использовать только CreateProcessAsUser или CreateProcessWithLogonW (нельзя использовать ShellExecute (Ex)), чтобы указать интерактивный рабочий стол.
.. Я думаю, что нет прямого способа порождать повышенный процесс с окна. Мы можем только сначала использовать CreateProcessAsUser или CreateProcessWithLogonW, чтобы создать невыполненный процесс в пользователе сеанс (интерактивный рабочий стол). Затем в невозбужденный процесс, он может использовать ShellExecute (Ex), чтобы создать процесс для реальной задачи.
Чтобы сделать это из кода .net/powershell, похоже, что мне нужно будет сделать некоторые сложные материалы P/Invoke для вызова CreateProcessAsUser или CreateProcessWithLogonW, поскольку .Net System.Diagnostics.ProcessStartInfo не имеет эквивалента lpDesktop что я могу установить "winsta0\default". И я не понимаю, есть ли у LocalSystem права называть CreateProcessAsUser или CreateProcessWithLogonW.
Я также посмотрел http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx а также Process.Start с разными учетными данными с UAC в
Исходя из всего этого, я пришел к выводу, что нет простого способа сделать это. Я что-то упускаю? Это действительно не похоже, что это должно быть так сложно. Похоже, что UAC никогда не был разработан для обработки неинтерактивных случаев использования.
И если кто-то из людей Microsoft в конечном итоге прочитает это, я заметил, что способ, которым ShellExecute внутренне обрабатывает возвышение, - это обратиться в Службу информации о приложениях (AIS). Почему не один и тот же вызов AIS доступен через некоторые API Win32 или .NET? http://msdn.microsoft.com/en-us/library/bb756945.aspx
Извините, что немного поработал. Спасибо за любые идеи.