Устранение ошибок доступа при быстрой смене пользователя в Windows через CreateProcessAsUser для внешних программ на Delphi и Pascal
Вопрос, поднятый в теме, заключается в проблеме выполнения внешних программ под учетной записью текущего пользователя в операционных системах семейства Windows, когда осуществляется быстрая смена пользователя. Разработчик столкнулся с ошибкой доступа при попытке запуска программы после смены пользователя без закрытия сессии. Проблема была обнаружена в коде, использующем функцию CreateProcessAsUser, которая некорректно работала в режиме быстрой смены пользователя.
Описание проблемы
Разработчик создал сервис, который должен автоматически запускать внешнюю программу для пользователя, находящегося в сессии, без его взаимодействия. Сервис обнаруживает идентификатор сессии пользователя и запускает внешнюю программу, используя полученные данные. При быстрой смене пользователя без закрытия сессии возникает ошибка доступа.
Контекст
В контексте был представлен пример кода на Object Pascal, который используется для запуска программы под учетной записью текущего пользователя. Код использует функции WTSQueryUserToken, CreateProcessAsUser, ProcessIdToSessionId и другие для определения и запуска процесса.
Подтвержденный ответ
Проблема заключалась в неправильном использовании токенов безопасности и настройке окружения запускаемого процесса. В подтвержденном ответе предложено использовать функцию WTSGetActiveConsoleSessionId для получения идентификатора активной консольной сессии, а затем WTSQueryUserToken для получения токена пользователя. Также рекомендуется использовать CreateEnvironmentBlock для создания окружения, соответствующего учетной записи пользователя, и DuplicateTokenEx для преобразования токена в первичный, необходимый для CreateProcessAsUser. Важно установить поле STARTUPINFO.lpDesktop в значение 'WinSta0\Default' для корректного отображения пользовательского интерфейса.
Альтернативный ответ
Альтернативный ответ предложил использовать уведомления о смене сессии с помощью WTSRegisterSessionNotification, чтобы получать уведомления о смене сессии и запускать внешнюю программу с учетом текущего пользователя.
Пример кода
function RunInteractive(prog_filename: String): Boolean;
var
hUserToken, hToken: THandle;
si: _STARTUPINFOA;
pi: _PROCESS_INFORMATION;
SessionId, Env: Pointer;
begin
Result := False;
ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);
si.lpDesktop := 'WinSta0\Default';
SessionId := WTSGetActiveConsoleSessionId;
if SessionId = $FFFFFFFF then Exit;
if not WTSQueryUserToken(SessionId, hToken) then Exit;
try
if not DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityIdentification, TokenPrimary, hUserToken) then Exit;
finally
CloseHandle(hToken);
end;
try
if not CreateEnvironmentBlock(Env, hUserToken, False) then Exit;
try
Result := CreateProcessAsUser(hUserToken, nil, PChar(prog_filename), nil, nil, False, CREATE_UNICODE_ENVIRONMENT, Env, PChar(ExtractFilePath(prog_filename)), si, pi);
if Result then
begin
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
end;
finally
DestroyEnvironmentBlock(Env);
end;
finally
CloseHandle(hUserToken);
end;
end;
Заключение
Проблема была вызвана некорректной работой с токенами безопасности и окружением процесса. Использование рекомендованных функций и правильная настройка параметров запуска позволяют запускать внешние программы под учетной записью текущего пользователя даже в режиме быстрой смены пользователя.
Комментарии и дополнения
В ходе обсуждения было выявлено, что проблема может быть связана с функциями из библиотеки JCL, которые вызывают ошибку доступа. Рекомендуется использовать стандартные функции Windows API для получения имени пользователя и домена, а также обратить внимание на безопасность и права доступа к файлам и ресурсам.
Примечание
Статья подготовлена в соответствии с требованиями SEO для сайта, специализирующегося на Delphi и Pascal, с учетом рекомендаций по использованию Object Pascal и примеров кода на этом языке программирования.
### Описание контекста:
Разработчик столкнулся с проблемой запуска внешних программ под учетной записью текущего пользователя в Windows при использовании функции `CreateProcessAsUser` в условиях быстрой смены пользователя, что привело к ошибкам доступа.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.