Sysutils pascal что это

Executing External Programs/ru

Contents

Введение: сравнение

В библиотеках RTL, FCL, LCL есть разные способы выполнить внешнюю программу.

Метод Библиотека Платформы Одной строкой? Особенности
ExecuteProcess RTL кроссплатформенный Да Очень ограничен, синхронен
ShellExecute WinAPI Только MS Windows Да Много. Может запускать программы с правами администратора
fpsystem, fpexecve Unix Unix only
TProcess FCL кроссплатформенный Нет Все
RunCommand FCL кроссплатформенный Требуется FPC 2.6.2+ Да Покрывает стандартное использование TProcess
OpenDocument LCL кроссплатформенный Да Только открывает документ. Документ будет открыт стандартной программой

Если вы использовали ShellExecute и/или WinExec в Delphi, то вы можете начать использовать TProcess как альтернативу в FPC/Lazarus (это верно и в случае использования Lazarus на Linux, потому что TProcess является кроссплатформенным компонентом).

Примечание: FPC/Lazarus поддерживает ShellExecute и WinExec, но только в среде Win32. Если вы пишете кросс-платформенную программу, то лучшим путем будет использование TProcess!

(Process.)RunCommand

В FPC 2.6.2, некоторые вспомогательные функции для TProcess были добавлены в модуль process основанный на обертке использованной в fpcup. Эти функции могут быть для базового и среднего уровня использования и могот захватить вывод как одной строки, так и огромного количества выводимой информации.

Перегруженный вариант функции может возвращать код выхода программы. RunCommandInDir запускает программу в заданной папке.

SysUtils.ExecuteProcess

MS Windows : CreateProcess, ShellExecute и WinExec

Примечание: FPC/Lazarus поддерживают CreateProcess, ShellExecute и/или WinExec, только на Win32/64. Если ваша программа кроссплатформенная, используйте RunCommand или TProcess.

Примечание: WinExec использует 16-битные вызовы и давно устарел. Новые версии FPC при его использовании генерируют предупреждение.

В качестве fMask можно ипользовать SEE_MASK_DOENVSUBST, SEE_MASK_FLAG_NO_UI или SEE_MASK_NOCLOSEPROCESS и тд Если в Delphi вы используете ShellExecute для открытия документов, например документ Word или ссылки, то присмотритесь к open* (OpenURL и т.д.) модуле lclintf.

Использование ShellExecuteEx с повышенными (правами администратора) правами

Если вы хотите использовать программу с повышенными (правами администратора) правами, используйте runas как альтернативу ShellExecuteEx:

Unix fpsystem, fpexecve и shell

Эти функции являются платформозависимыми.

Учтите, что Unix.Shell версии 1.0.x устарел и удален из trunk. Используйте fpsystem.

TProcess

Вы можете использовать TProcess для запуска внешних программ. Самыми полезными вещами при этом будут:

Примечание: TProcess не оболочка! И не терминал! Вы не можете напрямую исполнять скрипты или перенаправлять вывод используя такие операторы, как «

Важно: Вы должны определять полный путь к исполняемому файлу. Например ‘/bin/cp’ вместо ‘cp’. Если программа находится где-либо в переменной PATH, то вы можете использовать функцию FindDefaultExecutablePath из модуля LCL FileUtil.

Простейший пример

Многие типичные случаи были подготовлены в функциях Runcommand. Прежде, чем начать копировать и вставлять приведенные ниже примеры, сначала проверьте их.

Простой пример

Вот оно! Теперь вы научились запускать внешнюю программу изнутри вашей собственной.

Прим.перев.: на момент правки статьи (fpc 3.0.4) свойство CommandLine (как и ApplicationName) согласно документации объявлены deprecated. Вместо них рекомендуется использовать свойства Parameters и Executable соответственно.

Примечание: строковый агрумент, добавляемый в Parameters, не должен содержать пробелы.

Усовершенствованный пример (но пока не правильный)

Это все замечательно, но как я могу получить вывод программы, которую я запустил? Что ж, давайте немного расширим наш пример и сделаем так: этот пример прост, поэтому вы можете извлечь из него уроки. Пожалуйста, не используйте этот пример в рабочем коде, а используйте код из раздела Чтение больших объемов вывода

Чтение больших объемов вывода

В предыдущем примере мы ждали завершения запущенной программы. После этого мы считывали все, что программа записала в выходной поток. Но ведь может оказаться и так, что программа выведет много данных, канал заполнится и вывод остановится, при этом запустившая программа ждет завершения запущенной программы, которая в свою очередь не может завершить работу, пока не выведет все данные. Возникает коллизия, dead-lock.

Поэтому следующий пример не будет использовать опцию poWaitOnExit и будет читать данные при запущенной программе. Вывод записывается в поток, который можно позже использовать для чтения его содержимого в TStringList.

Если вы хотите считывать выходные данные из внешнего процесса, вы должны адаптировать этот код для повседневного использования.

Прим.перев.: можно выводить данные сразу в какой-нибудь memoOutput на основе (решения, предложенного пользователем KpjComp):

Обратите внимание, что вышеперечисленное также может быть достигнуто с использованием RunCommand:

Использование ввода и вывода TProcess

Смотри демо пример на Lazarus-CCR SVN.

Некоторые подсказки при использовании TProcess

Если вы создаете кроссплатформенную программу, вы можете изменять командную строку применительно к каждой ОС использую директивы «<$IFDEF>» и «<$ENDIF>«.

Показ комплекта приложений на переднем плане в macOS

Вы можете запустить application bundle(пакет приложения) через TProcess, вызвав исполняемый файл внутри пакета. Например:

Это запустит Calendar, но окно будет позади текущего приложения. Чтобы получить приложение на переднем плане, вы можете использовать утилиту open с параметром -n:

Если вашему приложению нужны параметры, вы можете передать open параметр —args, после чего все параметры будут переданы приложению:

Запуск отдельной программы

Обычно программа, запускаемая вашим приложением, является дочерним процессом и уничтожается, когда ваше приложение уничтожается. Если вы хотите запустить автономную программу, которая продолжает работать [после завершения вашего приложения], вы можете использовать следующее:

Пример «общения» с процессом aspell

Внутри исходного кода pasdoc вы можете найти два модуля, которые выполняют проверку орфографии, «общаясь» с запущенным процессом aspell через каналы:

Оба модуля довольно независимы от остальных исходников pasdoc, поэтому они могут служить реальными примерами использования TProcess для запуска и связи по каналам с другой программой.

«»> Замена операторов командной оболочки, таких как «| «

Иногда у вас есть желание выполнить более сложную команду, которая передает свои данные другой команде или файлу. Что-то вроде

Читайте также:  мобильная группа охраны что это такое

Запуск таких команд с TProcess не будет работать. То есть:

Почему использование специальных операторов для перенаправления вывода не работает

Как перенаправить вывод с помощью TProcess

Вы можете перенаправлять вывод команды другой команде, используя экземпляр TProcess для каждой команды.

Вот пример, который объясняет, как перенаправить вывод одного процесса другому. Чтобы перенаправить вывод процесса в файл/поток, см. пример чтение больших объемов вывода.

Вы можете не только перенаправлять «обычный» вывод (также известный как stdout), но также можете перенаправить вывод ошибок (stderr), если вы укажете опцию poStderrToOutPut, как видно в настройках для второго процесса.

Вот и все. Теперь вы можете перенаправлять вывод из одной программы в другую.

Заметки

Этот пример может показаться излишним, поскольку можно запускать «сложные» команды, используя оболочку с TProcess, например:

Но наш пример более кроссплатформенный, так как он не нуждается в модификации для работы в Windows или Linux и т.д. «sh» может существовать или не существовать на вашей платформе и обычно доступен только на платформах *nix. Кроме того, у нас больше гибкости в нашем примере, так как вы можете читать и записывать из/в ввода, вывода и stderr каждого процесса в отдельности, что может быть очень выгодно для вашего проекта.

Перенаправление ввода и вывода и запуск под Root

Распространенная проблема в Unix(macOS) и Linux заключается в том, что вы хотите выполнить какую-либо программу под учетной записью root (или, в более общем случае, под другой учетной записью пользователя). В качестве примера можно привести команду ping.

Большие части этого кода похожи на предыдущий пример, но он также показывает, как перенаправить stdout и stderr процесса, вызываемого отдельно, в stdout и stderr нашего собственного кода.

Другие мысли: Без сомнения, было бы целесообразно проверить, запрашивает ли sudo пароль. Это можно последовательно проверить, установив переменную окружения SUDO_PROMPT в ту, которую мы наблюдаем при чтении стандартного вывода TProcess, чтобы избежать проблемы, связанной с тем, что приглашение будет различным для разных локалей. Установка переменной среды приводит к тому, что значения по умолчанию очищаются (наследуются от нашего процесса), поэтому мы должны при необходимости скопировать окружение из нашей программы.

Использование fdisk с sudo в Linux

В следующем примере показано, как запустить fdisk на компьютере с Linux с помощью команды sudo для получения прав root.

Примечание: это только пример, и он не рассчитан на большой результат

Параметры, содержащие пробелы (замена кавычек оболочки Shell)

В оболочке Linux можно записать в кавычки следующие аргументы:

И GDB получит 3 аргумента (в дополнение к первому аргументу, который является полным путем к исполняемому файлу):

TProcess также может передавать параметры, содержащие пробелы, но использует другой стиль квотирования. Вместо того, чтобы заключать в кавычки только часть параметра, заключите в кавычки все из них. Вот так:

И также не забудьте передать только полный путь.

Смотрите также эту дискуссию об этом: здесь

Альтернативные решения с помощью LCLIntf

Иногда вам не нужно явно вызывать внешнюю программу, чтобы получить необходимую вам функциональность. Вместо того, чтобы открывать приложение и указывать документ для него, просто попросите ОС открыть документ, позволив ей использовать приложение по умолчанию, связанное с этим типом файла. Ниже приведены некоторые примеры.

Открытие документа в приложении по умолчанию

В некоторых ситуациях вам нужно открыть какой-либо документ/файл с использованием приложения по умолчанию, а не выполнить определенную программу. Это зависит от запущенной операционной системы. Lazarus предоставляет платформ-независимую процедуру OpenDocument, которая будет делать это за вас. Ваше приложение продолжит работу, не дожидаясь закрытия процесса документа.

Открытие web-страницы в web-браузере по умолчанию

Просто передайте требуемый URL, http:// в начале строки является необязательным при определенных условиях. Кроме того, передача имени файла дает те же результаты, что и OpenDocument()

Кроме того, вы можете использовать TProcess как в данном примере:

Источник

Executing External Programs/ru

Contents

Введение: сравнение

В библиотеках RTL, FCL, LCL есть разные способы выполнить внешнюю программу.

Метод Библиотека Платформы Одной строкой? Особенности
ExecuteProcess RTL кроссплатформенный Да Очень ограничен, синхронен
ShellExecute WinAPI Только MS Windows Да Много. Может запускать программы с правами администратора
fpsystem, fpexecve Unix Unix only
TProcess FCL кроссплатформенный Нет Все
RunCommand FCL кроссплатформенный Требуется FPC 2.6.2+ Да Покрывает стандартное использование TProcess
OpenDocument LCL кроссплатформенный Да Только открывает документ. Документ будет открыт стандартной программой

Если вы использовали ShellExecute и/или WinExec в Delphi, то вы можете начать использовать TProcess как альтернативу в FPC/Lazarus (это верно и в случае использования Lazarus на Linux, потому что TProcess является кроссплатформенным компонентом).

Примечание: FPC/Lazarus поддерживает ShellExecute и WinExec, но только в среде Win32. Если вы пишете кросс-платформенную программу, то лучшим путем будет использование TProcess!

(Process.)RunCommand

В FPC 2.6.2, некоторые вспомогательные функции для TProcess были добавлены в модуль process основанный на обертке использованной в fpcup. Эти функции могут быть для базового и среднего уровня использования и могот захватить вывод как одной строки, так и огромного количества выводимой информации.

Перегруженный вариант функции может возвращать код выхода программы. RunCommandInDir запускает программу в заданной папке.

SysUtils.ExecuteProcess

MS Windows : CreateProcess, ShellExecute и WinExec

Примечание: FPC/Lazarus поддерживают CreateProcess, ShellExecute и/или WinExec, только на Win32/64. Если ваша программа кроссплатформенная, используйте RunCommand или TProcess.

Примечание: WinExec использует 16-битные вызовы и давно устарел. Новые версии FPC при его использовании генерируют предупреждение.

В качестве fMask можно ипользовать SEE_MASK_DOENVSUBST, SEE_MASK_FLAG_NO_UI или SEE_MASK_NOCLOSEPROCESS и тд Если в Delphi вы используете ShellExecute для открытия документов, например документ Word или ссылки, то присмотритесь к open* (OpenURL и т.д.) модуле lclintf.

Читайте также:  Uplink normal что это

Использование ShellExecuteEx с повышенными (правами администратора) правами

Если вы хотите использовать программу с повышенными (правами администратора) правами, используйте runas как альтернативу ShellExecuteEx:

Unix fpsystem, fpexecve и shell

Эти функции являются платформозависимыми.

Учтите, что Unix.Shell версии 1.0.x устарел и удален из trunk. Используйте fpsystem.

TProcess

Вы можете использовать TProcess для запуска внешних программ. Самыми полезными вещами при этом будут:

Примечание: TProcess не оболочка! И не терминал! Вы не можете напрямую исполнять скрипты или перенаправлять вывод используя такие операторы, как «

Важно: Вы должны определять полный путь к исполняемому файлу. Например ‘/bin/cp’ вместо ‘cp’. Если программа находится где-либо в переменной PATH, то вы можете использовать функцию FindDefaultExecutablePath из модуля LCL FileUtil.

Простейший пример

Многие типичные случаи были подготовлены в функциях Runcommand. Прежде, чем начать копировать и вставлять приведенные ниже примеры, сначала проверьте их.

Простой пример

Вот оно! Теперь вы научились запускать внешнюю программу изнутри вашей собственной.

Прим.перев.: на момент правки статьи (fpc 3.0.4) свойство CommandLine (как и ApplicationName) согласно документации объявлены deprecated. Вместо них рекомендуется использовать свойства Parameters и Executable соответственно.

Примечание: строковый агрумент, добавляемый в Parameters, не должен содержать пробелы.

Усовершенствованный пример (но пока не правильный)

Это все замечательно, но как я могу получить вывод программы, которую я запустил? Что ж, давайте немного расширим наш пример и сделаем так: этот пример прост, поэтому вы можете извлечь из него уроки. Пожалуйста, не используйте этот пример в рабочем коде, а используйте код из раздела Чтение больших объемов вывода

Чтение больших объемов вывода

В предыдущем примере мы ждали завершения запущенной программы. После этого мы считывали все, что программа записала в выходной поток. Но ведь может оказаться и так, что программа выведет много данных, канал заполнится и вывод остановится, при этом запустившая программа ждет завершения запущенной программы, которая в свою очередь не может завершить работу, пока не выведет все данные. Возникает коллизия, dead-lock.

Поэтому следующий пример не будет использовать опцию poWaitOnExit и будет читать данные при запущенной программе. Вывод записывается в поток, который можно позже использовать для чтения его содержимого в TStringList.

Если вы хотите считывать выходные данные из внешнего процесса, вы должны адаптировать этот код для повседневного использования.

Прим.перев.: можно выводить данные сразу в какой-нибудь memoOutput на основе (решения, предложенного пользователем KpjComp):

Обратите внимание, что вышеперечисленное также может быть достигнуто с использованием RunCommand:

Использование ввода и вывода TProcess

Смотри демо пример на Lazarus-CCR SVN.

Некоторые подсказки при использовании TProcess

Если вы создаете кроссплатформенную программу, вы можете изменять командную строку применительно к каждой ОС использую директивы «<$IFDEF>» и «<$ENDIF>«.

Показ комплекта приложений на переднем плане в macOS

Вы можете запустить application bundle(пакет приложения) через TProcess, вызвав исполняемый файл внутри пакета. Например:

Это запустит Calendar, но окно будет позади текущего приложения. Чтобы получить приложение на переднем плане, вы можете использовать утилиту open с параметром -n:

Если вашему приложению нужны параметры, вы можете передать open параметр —args, после чего все параметры будут переданы приложению:

Запуск отдельной программы

Обычно программа, запускаемая вашим приложением, является дочерним процессом и уничтожается, когда ваше приложение уничтожается. Если вы хотите запустить автономную программу, которая продолжает работать [после завершения вашего приложения], вы можете использовать следующее:

Пример «общения» с процессом aspell

Внутри исходного кода pasdoc вы можете найти два модуля, которые выполняют проверку орфографии, «общаясь» с запущенным процессом aspell через каналы:

Оба модуля довольно независимы от остальных исходников pasdoc, поэтому они могут служить реальными примерами использования TProcess для запуска и связи по каналам с другой программой.

«»> Замена операторов командной оболочки, таких как «| «

Иногда у вас есть желание выполнить более сложную команду, которая передает свои данные другой команде или файлу. Что-то вроде

Запуск таких команд с TProcess не будет работать. То есть:

Почему использование специальных операторов для перенаправления вывода не работает

Как перенаправить вывод с помощью TProcess

Вы можете перенаправлять вывод команды другой команде, используя экземпляр TProcess для каждой команды.

Вот пример, который объясняет, как перенаправить вывод одного процесса другому. Чтобы перенаправить вывод процесса в файл/поток, см. пример чтение больших объемов вывода.

Вы можете не только перенаправлять «обычный» вывод (также известный как stdout), но также можете перенаправить вывод ошибок (stderr), если вы укажете опцию poStderrToOutPut, как видно в настройках для второго процесса.

Вот и все. Теперь вы можете перенаправлять вывод из одной программы в другую.

Заметки

Этот пример может показаться излишним, поскольку можно запускать «сложные» команды, используя оболочку с TProcess, например:

Но наш пример более кроссплатформенный, так как он не нуждается в модификации для работы в Windows или Linux и т.д. «sh» может существовать или не существовать на вашей платформе и обычно доступен только на платформах *nix. Кроме того, у нас больше гибкости в нашем примере, так как вы можете читать и записывать из/в ввода, вывода и stderr каждого процесса в отдельности, что может быть очень выгодно для вашего проекта.

Перенаправление ввода и вывода и запуск под Root

Распространенная проблема в Unix(macOS) и Linux заключается в том, что вы хотите выполнить какую-либо программу под учетной записью root (или, в более общем случае, под другой учетной записью пользователя). В качестве примера можно привести команду ping.

Большие части этого кода похожи на предыдущий пример, но он также показывает, как перенаправить stdout и stderr процесса, вызываемого отдельно, в stdout и stderr нашего собственного кода.

Читайте также:  макет в кривых что это значит

Другие мысли: Без сомнения, было бы целесообразно проверить, запрашивает ли sudo пароль. Это можно последовательно проверить, установив переменную окружения SUDO_PROMPT в ту, которую мы наблюдаем при чтении стандартного вывода TProcess, чтобы избежать проблемы, связанной с тем, что приглашение будет различным для разных локалей. Установка переменной среды приводит к тому, что значения по умолчанию очищаются (наследуются от нашего процесса), поэтому мы должны при необходимости скопировать окружение из нашей программы.

Использование fdisk с sudo в Linux

В следующем примере показано, как запустить fdisk на компьютере с Linux с помощью команды sudo для получения прав root.

Примечание: это только пример, и он не рассчитан на большой результат

Параметры, содержащие пробелы (замена кавычек оболочки Shell)

В оболочке Linux можно записать в кавычки следующие аргументы:

И GDB получит 3 аргумента (в дополнение к первому аргументу, который является полным путем к исполняемому файлу):

TProcess также может передавать параметры, содержащие пробелы, но использует другой стиль квотирования. Вместо того, чтобы заключать в кавычки только часть параметра, заключите в кавычки все из них. Вот так:

И также не забудьте передать только полный путь.

Смотрите также эту дискуссию об этом: здесь

Альтернативные решения с помощью LCLIntf

Иногда вам не нужно явно вызывать внешнюю программу, чтобы получить необходимую вам функциональность. Вместо того, чтобы открывать приложение и указывать документ для него, просто попросите ОС открыть документ, позволив ей использовать приложение по умолчанию, связанное с этим типом файла. Ниже приведены некоторые примеры.

Открытие документа в приложении по умолчанию

В некоторых ситуациях вам нужно открыть какой-либо документ/файл с использованием приложения по умолчанию, а не выполнить определенную программу. Это зависит от запущенной операционной системы. Lazarus предоставляет платформ-независимую процедуру OpenDocument, которая будет делать это за вас. Ваше приложение продолжит работу, не дожидаясь закрытия процесса документа.

Открытие web-страницы в web-браузере по умолчанию

Просто передайте требуемый URL, http:// в начале строки является необязательным при определенных условиях. Кроме того, передача имени файла дает те же результаты, что и OpenDocument()

Кроме того, вы можете использовать TProcess как в данном примере:

Источник

File Handling In Pascal/ru

Contents

Введение

Каждый программист должен знать, как работать с файлами. Файлы используются для сохранения данных, т. е. в качестве хранилища данных, таким образом, что они могут быть получены в любой момент, без их воссоздания. Файлы можно использовать для сохранения пользовательских настроек, журналов ошибок, измерение или вычисление результатов, и многое другое. В данном разделе описываются основы использования файлов.

Процедурный стиль

Ниже представлены примеры создания собственных типов файлов:

Обработка ошибок ввода/вывода

Параметр компилятора обработки ошибок ввода/вывода указывает, как должна вести себя программа при возникновении ошибки в процессе работы с файлами: вызвать исключение или хранить результат операции ввода/вывода в специальной переменной IOResult.

Это задаётся с помощью специальной директивы компилятора:

В случаи подавления ошибок ввода-вывода (<$I->) результат операции с файлом будет храниться в переменной IOResult типа cardinal (числовой тип). Каждое число, хранимое в IOResult определяет тип возникшей ошибки(подробнее: [1]).

Процедуры работы с файлами

Эти процедуры и функции находятся в модуле system. Для более подробной информации смотрите документацию FPC:

Пример

Пример работы с текстовым файлом (тип TextFile):

Теперь откройте файл в любом текстовом редакторе и вы увидите, что пример текста, записан в нем! Вы можете проверить работу обработки ошибок, установив атрибут файла «только для чтения» и снова запустив программу.

Обратите внимание, что в примере используется блок try/except. Данный способ позволяет выполнять несколько операций с файлами и использовать обработку исключений. Вы также можете использовать режим <$I->, но тогда вам придется проверять переменную IOResult после каждой операции с файлами для контроля ошибок.

Ниже приведен пример записи текста в конец файла:

Чтение текстового файла:

Объектный стиль

В дополнение к старому методу обработки файлов, упомянутому выше процедурному стилю, существует новая система, которая использует концепции потоков (данных) на более высоком уровне абстракции. Это означает, что данные могут считываться или записываться в любом месте (диск, память, аппаратные порты и т. д.) через один универсальный интерфейс.

Кроме того, большинство классов обработки строк, могут иметь возможность загружать/сохранять содержимое из/в файл. Эти методы обычно называются SaveToFile и LoadFromFile.

Двоичные файлы

Для прямого доступа к файлам, так же удобно использовать класс TFileStream. Этот класс представляет собой инкапсуляцию системных процедур FileOpen, FileCreate, FileRead, FileWrite, FileSeek и FileClose, расположенных в модуле SysUtils.

В приведенном ниже примере обратите внимание, что обработка действий с файлом, расположена внутри блока try..except. Поэтому обработка ошибок происходит так же, как в случаи использования процедур работы с файлами в классическом Pascal.

Вы так же можете загрузить весь файл в память, если его размер существенно меньше, чем имеющийся системной памяти. Если файл превышает размер системной памяти, то ваша операционная система начнет использовать файл подкачки, снижая скорость работы с файлом.

Для работы с файлами большого объёма, рекомендуется использовать буфер, например в 4096 байт.

Копирование файла

Теперь,зная методы работы с файлами, мы можем реализовать простую функцию копирования файла, скажем FileCopy.(такой функции нет в FreePascal, хотя Lazarus её имеет copyfile):

Обработка текстовых файлов (TStringList)

Для текстовых файлов можно использовать класс TStringList, чтобы загрузить весь файл в память и иметь легкий доступ к его строкам. Вы также можете записать StringList обратно в файл:

Демо: сохранить одну строку в файл

Для того, чтобы сохранить одну строку в файл, вы можете воспользоваться процедурой, описанной ниже.

Источник

Образовательный портал