![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Ожидание завершения асинхронных подпроцессов в консольных приложениях на DelphiDelphi , ОС и Железо , DOS и КонсольПочему командный интерпретатор не возвращается после вызова WinExec?Вопрос, который рассмотрен в данной статье, связан с использованием функции WinExec в консольном приложении на Delphi для вызова утилиты echo.exe из Cygwin с целью вывода цветного текста. Cygwin установлен в директории C:\cygwin, а его echo.exe находится по адресу C:\cygwin\bin\echo.exe. Автор выбрал WinExec вместо ShellExecute, так как последний запускает новый оболочку, что не требуется в данном случае. Попытка №1При первом запуске программы, как видно на изображении, командный интерпретатор не возвращается к приглашению. Автор предполагал, что WinExec не завершил свою работу или ожидает какую-то команду переноса строки. Пример кода программы:
Попытка №2Во второй попытке, как показано на следующем изображении, ясно, что WinExec уже завершил свою работу. Однако командный интерпретатор все еще не возвращается к приглашению. Автор был сбит с толку и обратился за комментариями. Пример кода с добавлением записи возвращаемого значения WinExec:
Альтернативный ответ и комментарииАвторы комментариев предложили использовать функции WinAPI для работы с консолью вместо вызова Cygwin's echo, что выглядит более подходящим для Windows-приложения. Также было отмечено, что использование WinExec является устаревшим методом. Подтвержденный ответОказывается, оболочка уже вернулась к приглашению до того, как цветной текст был напечатан. Это видно по тому, что оболочка печатает приглашение. Она бы не сделала этого, если бы ожидала завершения программы. Это можно проверить, введя дополнительные команды в приглашении и наблюдая за их выполнением. Когда вы вызываете WinExec, программа запускается асинхронно. Функция не ожидает завершения команды echo перед возвратом контроля вашей программе, и ваша программа также не ожидает завершения команды. Поскольку оболочка ожидает только завершения вашей программы, она печатает свое приглашение сразу после завершения вашей программы, что происходит до того, как команда echo успевает напечатать какой-либо вывод. Чтобы решить эту проблему, необходимо дождаться завершения команды echo перед завершением собственной программы. WinExec не позволяет это сделать, и это хорошо, поскольку он устарел уже на протяжении 17 лет. Вместо этого следует использовать CreateProcess. Он возвращает дескриптор процесса, который можно передать в WaitForSingleObject, который будет блокировать до завершения процесса. Рекомендуемое решениеИспользуйте функцию CreateProcess для запуска подпроцесса, а затем дождитесь его завершения с помощью WaitForSingleObject. Это позволит вашей программе ожидать завершения асинхронного подпроцесса перед тем, как продолжить выполнение.
Этот код демонстрирует, как запустить подпроцесс и дождаться его завершения, после чего программа продолжит выполнение и вернет контроль пользователю, предоставив ему возможность видеть вывод команды в консоли, без блокировки оболочки. Вопрос связан с проблемой, когда командный интерпретатор не возвращается к приглашению после вызова функции WinExec в консольном приложении на Delphi для запуска утилиты echo.exe из Cygwin с целью вывода цветного текста, и предлагается решение с использо Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: DOS и Консоль ::
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |