Устранение проблемы ввода в cmd.exe при запуске от имени администратора в Delphi
Описание проблемы:
Разработчики часто сталкиваются с проблемой, когда их приложение, предназначенное для отправки ввода в cmd.exe, работает корректно при запуске командной строки от имени обычного пользователя, но терпит неудачу, когда cmd запущен от имени администратора. Это связано с политикой изоляции пользовательского интерфейса (UIPI), которая предотвращает взаимодействие между приложениями с различными уровнями привилегий.
Пример кода, вызывающего проблему:
var
Wnd: HWND;
begin
Wnd := FindWindow('ConsoleWindowClass', NULL);
if Wnd <> 0 then
begin
SetForegroundWindow(Wnd);
Keybd_Event(Ord('A'), 0, 0, 0);
end;
end;
Этот код пытается установить cmd.exe в качестве активного окна и отправить ему ввод, но не работает, если cmd запущен от имени администратора.
Подтвержденный ответ:
Для решения этой проблемы необходимо, чтобы приложение, отправляющее ввод, также работало от имени администратора. Это позволит ему обойти ограничения, связанные с UIPI. Вот шаги, которые нужно предпринять:
Запустите cmd.exe от имени администратора.
Перекомпилируйте ваше приложение с включенным параметром "Run as administrator" в настройках проекта (например, в свойствах проекта в Delphi).
Альтернативное решение (с оговорками):
Вы можете включить UIAccess=true в запрашиваемые разрешения манифеста вашего приложения, что позволяет обойти UIPI для неэлеваторных приложений. Однако для этого приложение должно быть сертифицировано Authenticode и выполняться из защищенного каталога, например, %programfiles%. Кроме того, после установки с помощью элеватора, приложение может запускаться с разрешениями пользователя, сохраняя при этом возможность отправки ввода в элеваторные приложения.
Важные замечания:
Используйте SendInput() вместо устаревшего keybd_event().
Введение команд через виртуальную клавиатуру (osk.exe) также может помочь обойти ограничения UIPI.
Пример кода с использованием SendInput():
uses
Winapi.Windows,
Winapi.Messages;
procedure SendKeyToCmd(Key: Char);
var
Input: TInput;
begin
Input.dwFlags := KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
Input.time := 0;
Input.dwExtraInfo := 0;
case Key of
'A': Input.wVk := $1E; break;
// Добавьте другие символы и соответствующие коды
end;
SendInput(1, @Input, SizeOf(TInput));
end;
Этот код можно использовать во время разработке, когда cmd активно в фокусе, если выполнение кода не запрещается политиками безопасности и привилегиями процесса.
Напоминаем, что все операции с вводом и запуском программ от имени администратора требуют особой осторожности и понимания потенциальных рисков безопасности.
заключается в том, что разработчики сталкиваются с трудностями в отправке ввода в `cmd.exe`, когда она запущена от имени администратора из-за политики изоляции пользовательского интерфейса (UIPI).
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.