Ada_Ru форум

Обсуждение языка Ада

[ada_ru] Как выполнить из кода bat-скрипт или запустить bat-файл?

Оставить новое сообщение

Сообщения

Anton Zabeline
[ada_ru] Как выполнить из кода bat-скрипт или запустить bat-файл?
2020-04-22 20:15:13

Здравствуйте. Пол дня бился над этим вопросом, но так и не смог найти в сети внятных результатов. Суть вот в чём:

Нужно чтобы из небольшой программки, написанной на Аде выполнился скрипт "ping 127.0.0.1 -n 2 -w 1000" или батник, содержащий этот скрипт. В первом случае неясно, как заставить аду это выполнить. Во втором неясно как вызвать батник, чтобы он запустился в cmd (в C++ для этого есть функция "System"). Нужно сделать это именно так, другие способы не подойдут. Прошу прощения за возможно глупые вопросы. Прочитал информацию на вашем сайте про этот язык и вот оцениваю, стоит ли продолжать, хватит ли сил разобраться. Очень интересно, но вот такие моменты, как взаимодействие с Win API не совсем понятны. Буду очень благодарен за любую помощь или ткнуть носом в сторону тех, кто сможет объяснить. Ах да, я использую GNAT GPS, Win7 (64 bit).

В пакете "System.OS_Lib" есть всё что вам нужно.

(Файл: ... adainclude\s-os_lib.ads)

"ping 127.0.0.1 -n 2 -w 1000" -- это не скрипт, а вызов программы "ping.exe" (то что вызывается функцией "system" или другими функциями вызовов подпроцессов в СИ.

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

Спасибо, Сергей. Я правильно понимаю, что для того, чтобы запустился батник нужно использовать

function Spawn

(Program_Name : String;

Args : Argument_List) return Integer;?

Может есть какой нибудь пример на этот счёт? Совсем не понятно как это реализуется.

Чтобы запустить командный файл, нужно использовать для Program_Name -- "cmd.exe", в списке аргументов указать имя командного файла и аргументы командного файлы.

Чтобы посмотреть использование командного процессора наберите в консоли -- "cmd.exe /?".

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

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

On 23/04/2020 05:32, Dukov Sergey dukov54@live.ru [ada_ru] wrote:

 

Спасибо, Сергей. Я правильно понимаю, что для того, чтобы запустился батник нужно использовать

function Spawn

 

Верно, но не одновременно не верно. Так бывает.

Антон, мне кажется Вы путаете понятие батник и запуск процесса.

Если Вам надо чисто ping вызвать, то надо вызывать сразу ping.exe с нужными параметрами и читать его вывод.

Если все таки Вам надо вызывать батник, то не важно что там внутри написано, поскольку батник, это текстовый файл

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

$ find /App/gnat/share/ -name "*.ad?" | xargs grep Spawn

/App/gnat/share/examples/gnat/other_languages/old_compatibility/mycpp.adb: Spawn (GPP.all, Arg, Res);

В виндах он должен лежать там же относительно корня gnat.

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

К слову, Spawn там несколько штук есть. В зависимости от подробностей Вашей задачи надо выбрать который лучше подходит.

 

 

Успехов !

 

 

[Non-text portions of this message have been removed]

Привет,

 

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

Вот пример использования:

https://github.com/reznikmm/spawn/blob/master/testsuite/spawn/spawn_test.adb

Репозиторий тут:

https://github.com/reznikmm/spawn

 

Если интересует именно Win API, то можно скачать и поставить Win32Ada. Найти его можно на https://www.adacore.com/download/more

если зайти в "x86 Windows (32 bits)".

 

Удачи

Методом проб и ошибок наконец разобрался как запустить процесс. Вот в итоге что получилось:

 

procedure main is

 

Arg : Argument_List (1 .. Argument_Count + 1);

Res : Boolean;

ping : String_Access := Locate_Exec_On_Path ("C:\Windows\system32\ping.exe");

N : natural;

 

begin

if ping = null or else ping.all'Length <= 8 then

GNAT.IO.Put_Line ("No ping on path");

OS_Exit (1);

end if;

 

if ping.all (ping'last - 3 .. ping'last) = ".exe" then

N := 12;

else

N := 8;

end if;

 

declare

 

ping_Root : constant String := ping (1 .. ping.all'length - N);

begin

 

Arg (1) := new String' ("127.0.0.1 -n 2 -w 1000");

 

for I in 1 .. Arg'Last - 1 loop

Arg (I + 1) := new String'(Argument (I));

end loop;

 

Spawn (ping.all, Arg, Res);

end Main;

 

В итоге процесс успешно поднимается, но аргумент 127.0.0.1 -n 2 -w 1000 то ли передаётся с ошибкой, то ли передаётся неправильно. На выходе получается вот такое:

'При проверке связи не удалось обнаружить узел 127.0.0.1 -n 2 -w 1000. Проверьте имя узла и повторите попытку.'

При ручном вводе команды в CMD пинг успешно отрабатывается:

Обмен пакетами с 127.0.0.1 по с 32 байтами данных:

"Ответ от 127.0.0.1: число байт=32 время<1мс TTL=128

Ответ от 127.0.0.1: число байт=32 время<1мс TTL=128"

 

Пробовал использовать программу, в которой виден результат ввода: 'Ошибка: Неправильный параметр или аргумент - '/f /im notepad.exe'. Введите "TASKKILL /?" для получения справки по использованию.'

Отсюда видно, что параметры и аргумент передаются синтаксически правильно, но тем не менее, ошибка. При ручном вводе всё работает, блокнот закрывается.

Слышал про такую вещь как "экранирование символов". Но даже не представляю, как в Аде это делается и найти информации об этом не могу нигде. Может кто нибудь знает или поправит руки в нужном направлении? Вроде как всё просто должно быть, но уже несколько дней меняю бубны и толку ноль...

В списке аргументов "127.0.0.1", "-n", "2", "-w", "1000" -- это отдельные элементы массива строк. А у вас ping.exe получил в качестве адреса сроку "127.0.0.1 -n 2 -w 1000" и для него это полная ерунда!

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

Args : Argument_List := ("127.0.0.1", "-n", "2", "-w", "1000");

И этот массив передавайте в качестве второго параметра в процедуру "Spawn".

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

К сожалению, это не сработало. Ругается, что:

main.adb:9:24: incorrect number of index constraints for type "System.Os_Lib.Argument_List"

Я тут внимательно посмотрел. Оказывается Argument_List -- это не массив строк, а массив указателей на строки. Тогда так:

Args : Argument_List(1 .. 5);

...

...

Args(1) := new String' ("127.0.0.1");

Args(2) := new String' ("-n");

Args(3) := new String' ("2");

Args(4) := new String' ("-w");

Args(5) := new String' ("1000");

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

Я тут внимательно посмотрел. Оказывается Argument_List -- это не массив строк, а массив указателей на строки. Тогда так:

Или - проще - так:

Argument_String_To_List ("127.0.0.1 -n 2 -w 1000")

:)

@Антон, а каков сакральный смысл вот в этой строке?

ping : String_Access := Locate_Exec_On_Path ("C:\Windows\system32\ping.exe");

Зачем звать Искать_Программу_В_Пути, когда путь заранее известен? Функция же просто вернет без изменений свой параметр :)

Большое спасибо, Сергей. Этот вариант работает. Всё выполняется после удаления вот этого:

for I in 1 .. Arg'Last - 1 loop

Arg (I + 1) := new String'(Argument (I));

end loop;

Большое спасибо за помощь, теперь буду изучать с самых азов, возможности оценил. Не сочтите за оффтоп, просто спрошу напоследок:

В Аде можно писать текст кириллицей? Не комментарии, а именно текст для вывода?

P.S. насчёт строки "ping : String_Access := Locate_Exec_On_Path ("C:\Windows\system32\ping.exe");"

Я и сам не знаю :) Это строка из примера. А почему путь известен заранее? Как она узнаёт где лежит этот ping.exe?

On 28/04/2020 07:31, Anton Zabeline ada_ru@forge.ada-ru.org [ada_ru] wrote:

 

P.S. насчёт строки "ping : String_Access := Locate_Exec_On_Path ("C:\Windows\system32\ping.exe");"

Я и сам не знаю :) Это строка из примера. А почему путь известен заранее? Как она узнаёт где лежит этот ping.exe?

 

Путь известен заранее, потому что он записал в коде,

C:\Windows\system32\ping.exe - это есть полный абсолютный путь.

 

а вот если бы было записано

 

Locate_Exec_On_Path ("ping.exe") - тогда это имело бы смысл, потому что ping.exe будет искаться в путях, указанных в

 

переменной среды окружения PATH.

 

 

 

[Non-text portions of this message have been removed]

В Аде можно писать текст кириллицей? Не комментарии, а именно текст для вывода?

 

Можно, только нужно компилятор предупредить, какая кодировка используется. Если исходники в UTF-8 нужно использовать опцию компилятора `-gnatW8`. Ну и использовать правильные типы данных, т.к. в String нет русских букв, там только Latin-1 символы.

 

Вот пример

 

with Ada.Wide_Wide_Text_IO;

procedure Main is

begin

Ada.Wide_Wide_Text_IO.Put_Line ("Привет!");

end Main;

 

https://tio.run/##S0xJ1E3PSyz5/788syRDwTElUS88MyU1HkyEpFaUxHv6W3NxFRTlJ6emlBalKvgmZuYpZBYrcCWlpmfmcSkAAVZNegGlJfE@mXmpChpKF@ZfbLiw48KmC1svNikqaVpzpealgA2y/v//X3JaTmJ68X@wK8ItAA

Вот сейчас вопросов стало ещё больше. Куда именно нужно добавить флаг "-gnatW8"? В настройках у меня выставлена опция UTF-8 и сам редактор не ругается на кириллический шрифт. Но после компилляции и запуска exe, весь шрифт виден как "крякозябры"...

Пример присланный Максимом демонстрирует только тот факт, что GNAT правильно строит UTF-8 литералы. Даже можно использовать UTF-8 идентификаторы. Но под Windows он выводить на консоль стандартным способом он не умеет. Нужно иметь специальную библиотеку для вывода в консоль под Windows. Сам же Максим мне когда то её мне присылал. Сейчас на Яху-форуме нельзя пересылать файлы. Поищите на AdaCore ссылку "Minimal_Console" -- это библиотека вывода. У меня есть библиотека "Unicode_Console" -- это библиотека ввода/вывода.

С уважением и наилучшими пожеланиями,

Сергей Дюков,

Волжский.

Приет Сергей,

 

On 01/05/2020 00:18, Dukov Sergey dukov54@live.ru [ada_ru] wrote:

Поищите на AdaCore ссылку "Minimal_Console" -- это библиотека вывода.

Чего то не нашел. Может плохо искал ?

У меня есть библиотека "Unicode_Console" -- это библиотека ввода/вывода.

По запросу AdaCore Minimal_Console гугл выдал интересную ссылку по этой теме на твою страницу

http://www.rtsdd.ru/Ada2012_Unicode_NCURSES.aspx

в которой есть слово Minimal_Console

 

 

 

 

[Non-text portions of this message have been removed]

On Apr 30, 2020, at 20:18 , Dukov Sergey dukov54@live.ru [ada_ru] <ada_ru@yahoogroups.com> wrote:

Пример присланный Максимом демонстрирует только тот факт, что GNAT правильно строит UTF-8 литералы. Даже можно использовать UTF-8 идентификаторы. Но под Windows он выводить на консоль стандартным способом он не умеет.

Ну конечно!

Задайте команду "chcp 65001" и будет счастье, будет печатать пример Максима "Привет" как и полагается.

Народ, вас в гугле забанили что ли? Набрать запрос типа "windows console utf-8" и выбрать первый пункт из списка, нет?

Новое сообщение:
Страницы: 1 2

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти