Исполнение команд DOS из под приложения (графического)

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
Аватара пользователя
GN
новенький
Сообщения: 67
Зарегистрирован: 29.07.2007 07:35:56
Откуда: Казахстан
Контактная информация:

Исполнение команд DOS из под приложения (графического)

Сообщение GN »

Возможно ли исполнять досовские команды (например, dir, cd и т.п.) из обычного графического приложения (под окнами)?
Например, имеется компонент TEdit, в него вводят команды, и по горячей клавише или с помощью кнопки эта команда выполняется.
Или пусть даже будет задействовано cmd.exe только чтобы оно было свёрнутым.
serg_iv
постоялец
Сообщения: 276
Зарегистрирован: 15.10.2005 18:45:46
Откуда: Миасс

Сообщение serg_iv »

под Линуксум я для этого использовал TProcess. Думаю под виндой тоже прокатит. Примеры на форуме были, найди.
SAK
постоялец
Сообщения: 158
Зарегистрирован: 17.02.2006 23:45:14
Откуда: Тим
Контактная информация:

Сообщение SAK »

А зачем выполнять dir свёрнутым? Надо бы определиться в цели, зачем это надо, а потом уже выбирать путь решения. Если надо сменить каталог, то это можно сделать и не запуская внешнего приложения, и список файлов получается также. А если надо выполнять команды вводимые с клавиатуры, то лучше взять системную переменную COMSPEC, там прописан текущий командный процессор (cmd.exe или command.com) и запускать данную программу с параметром '/C '+<команда>.
Всё сказанное относится к работе под Windows или DOS.
Аватара пользователя
GN
новенький
Сообщения: 67
Зарегистрирован: 29.07.2007 07:35:56
Откуда: Казахстан
Контактная информация:

Сообщение GN »

"dir" я для примера написал.
Цель такова:
Имеется графическое приложение, на нём компонент TEdit, туда чел вводит команду (досовскую), нажимает кнопку, и она выполняется.
SAK
постоялец
Сообщения: 158
Зарегистрирован: 17.02.2006 23:45:14
Откуда: Тим
Контактная информация:

Сообщение SAK »

Самый простой пример:

Код: Выделить всё

program Project1;

uses DOS;
var
   command: string;
begin
  command:='dir';
  Exec(GetEnv('COMSPEC'), '/C '+command);
  Readln;
end.

Можно использовать GetEnvironmentVariable (в модуле windows) и TProcess вместо GetEnv и Exec.
Аватара пользователя
GN
новенький
Сообщения: 67
Зарегистрирован: 29.07.2007 07:35:56
Откуда: Казахстан
Контактная информация:

Сообщение GN »

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
   command: string;
   
begin

  command := 'systeminfo';
  Exec(GetEnv('COMSPEC'), command);
  Readln;
 
end;


При нажатии кнопки, cmd.exe открывается, но не выполняется команда, а в приложении выскакивает ошибка "File not open" :(
Аватара пользователя
GN
новенький
Сообщения: 67
Зарегистрирован: 29.07.2007 07:35:56
Откуда: Казахстан
Контактная информация:

Сообщение GN »

Во, а если так:

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
   command: string;
   
begin

  command := 'systeminfo';
  Exec(GetEnv('COMSPEC'), '/C ' + command);
  Readln;
 
end; 
То команда выполняется, и окно (досовское) сразу закрывается, и потом опять выходит ошибка "File not open"

-=-=-=
Если "Readln;" убрать, то ошибка исчезнет, но досовск. окно по прежнему закрывается
unC0Rr
новенький
Сообщения: 59
Зарегистрирован: 02.02.2006 02:44:44

Сообщение unC0Rr »

GN писал(а):Если "Readln;" убрать, то ошибка исчезнет, но досовск. окно по прежнему закрывается


Код: Выделить всё

Exec(GetEnv('COMSPEC'), '/K ' + command);
SAK
постоялец
Сообщения: 158
Зарегистрирован: 17.02.2006 23:45:14
Откуда: Тим
Контактная информация:

Сообщение SAK »

Правильно. /C - выполнить команду и выйти из командного процессора, /K - тоже самое, только не выходит из командного процессора, для выхода надо Exit набирать. У меня приведён пример консольного приложения, поэтому "File not open" не выскакивает на Readln, которая поставлена для ожидания нажатия Enter до закрытия окна. Для графического приложения надо искать другие способы оставить окно видимым.
Последний раз редактировалось SAK 21.09.2007 22:54:50, всего редактировалось 1 раз.
Аватара пользователя
GN
новенький
Сообщения: 67
Зарегистрирован: 29.07.2007 07:35:56
Откуда: Казахстан
Контактная информация:

Сообщение GN »

Всем большое спасибо. Получилось
Аватара пользователя
Attid
долгожитель
Сообщения: 2588
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

теперь читаем как получить вывод другой программы

и делаем все красивее =)
PapaNT
постоялец
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Сообщение PapaNT »

Вчера наткнулся на прикол обработки переменных DOS через getenv('temp') под Windows. На выходе получил "/cygdrive/c/Temp" :shock:
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

PapaNT
А у меня полный порядок - выдало "C:\Temp", как и положено...
PapaNT
постоялец
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Сообщение PapaNT »

Vadim писал(а):PapaNT
А у меня полный порядок - выдало "C:\Temp", как и положено...
странно. Я пробовал через модуль DOS GetEnv и через sysutils.GetEnivormentVariable...

Добавлено спустя 14 минут 38 секунд:
Re: Исполнение команд DOS из под приложения (графического)
File Edit Search Run Compile Debug Tools Opti
╔═[■]═════════════════════ D:\FPC\2.2.4\pas\tets.pas
║Program Env;

║Uses DOS,sysutils;
║Var
║ s : string;
║Begin
║ Writeln;
║ s := sysutils.GetEnvironmentVariable('Temp');
║ Writeln(s);
║ s := dos.getenv('Temp');
║ Writeln(s)
║End.
╚══════ 12:1 ═◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
┌────────────────────────────────── Watches ─────────
│ s = '/cygdrive/c/TEMP'

Оказалось, виноват пошаговый отладчик. Когда запускал по Ctrl + F9, то все прокатывло нормально, а при пошаговой отладке вылезала эта бага...
alexmai
постоялец
Сообщения: 106
Зарегистрирован: 02.02.2009 13:58:42

Сообщение alexmai »

мне кажется что можно использовать аналог старой C-ишной комманды -system

Код: Выделить всё

var  s: string;
...
для DOS
s:='r.bat < y.txt ';
//или для линукса 
s:='chmode a+rw '+filename ;

{$IFNDEF FPC}
    Libc.system(pchar(s));
{$ELSE}
    fpSystem(s);
{$ENDIF}

Ответить