Решение действительно зависит от ваших потребностей и может быть довольно сложным (полностью благодаря Windows Vista). Вероятно, это будет за пределами вашей потребности, но это поможет другим, которые находят эту страницу с помощью поиска.
- Если вам не нужен процесс для запуска с графическим интерфейсом, и вам не требуется повышение прав
- Если пользователь, которого вы хотите запустить от имени, уже вошел в сеанс
- Если вам нужно запустить процесс с графическим интерфейсом, и пользователь может или не может войти в систему
- Если вам нужно запустить процесс с возвышением
Относительно 1:
В Windows Vista существует нечто, называемое изоляцией сеанса 0. Все сервисы работают как сеанс 0, и вы не должны иметь графический интерфейс пользователя в сеансе 0. Первый вошедший в систему пользователь регистрируется в сеансе 1. В предыдущих версиях Windows (до Vista) первый вошедший в систему пользователь также полностью запускался в сессия 0.
Вы можете запускать несколько разных процессов с разными именами пользователей в одном сеансе. Хороший документ об изоляции сеанса 0 можно найти здесь .
Поскольку мы имеем дело с вариантом 1), вам не нужен графический интерфейс. Поэтому вы можете начать процесс в сеансе 0.
Вам понадобится последовательность вызовов примерно такая:
LogonUser, ExpandEnvironmentStringsForUser, GetLogonSID, LoadUserProfile, CreateEnvironmentBlock, CreateProcessAsUser.
Пример кода для этого можно найти через любую поисковую систему или через Поиск кода Google
Относительно 2: Если пользователь, которому вы хотите запустить процесс, уже вошел в систему, вы можете просто использовать: WTSEnumerateSessions и WTSQuerySessionInformation, чтобы получить идентификатор сеанса, а затем WTSQueryUserToken, чтобы получить пользовательский токен. Оттуда вы можете просто использовать токен пользователя в Win32 API CreateProcessAsUser.
Это отличный метод, потому что вам даже не нужно входить в систему как пользователь или знать имя пользователя / пароль пользователя. Я считаю, что это возможно только через службу, хотя и работает как локальная системная учетная запись.
Вы можете получить текущий сеанс через WTSGetActiveConsoleSessionId.
Относительно 3:
Вы будете следовать тем же шагам, что и # 1, но, кроме того, вы будете использовать поле lpDesktop в STARTUPINFO. Установите для этого значение winsta0 \ Default. Вам также нужно будет попробовать использовать OpenDesktop Win32 API, и в случае неудачи вы можете создать CreateDesktop. Перед использованием дескрипторов станции и рабочего стола вы должны использовать SetSecurityInfo для каждого из них с SE_WINDOW_OBJECT и GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION.
Если позже рассматриваемый пользователь попытается войти в систему, он фактически увидит запущенный процесс.
Относительно 4:
Это также можно сделать, но для этого требуется, чтобы у вас уже был запущенный процесс с повышенными правами. Служба, работающая как локальная системная учетная запись, работает с повышенными правами. Я мог также заставить его работать, только имея подписанный процесс authenticode, который я хотел запустить. Процесс, который вы хотите запустить, также должен иметь файл манифеста, связанный с ним с уровнем requiredExecutionLevel = "requireAdministrator"
Другие примечания:
- Вы можете установить сеанс токена с помощью SetTokenInformation и TokenSessionId
- Вы не можете изменить идентификатор сеанса уже запущенного процесса.
- Весь этот процесс был бы значительно проще, если бы в уравнении не было Vista.