|
Вопрос # 2 455/ вопрос открыт / |
|
Здравствуйте, эксперты!
Имеется программа, работающая под DOS, написана на Фортране и очень большой исходник – нет желания и возможности переписывать на Дельфи, тем более, что эта программа рекомендована Международным Союзом Электросвязи.
В оболочке, написанной на Дельфи, осуществляю запуск этого приложения так:
ShellExecute(Self.Handle,'open',PChar('Run.bat'),nil,nil,SW_HIDE);
где командый файл Run.bat содержит одну строку: GRWAVE.EXE <Input.inp >Output.out
Файл Input.inp содержит исходные данные, необходимые для расчетов; результаты выводятся в файл Output.out.
В ходе моих расчётов необходимо из оболочки изменять исходные данные в файле Input.inp и многократно запускать внешнее приложение.
Проблема: при первом вызове ShellExecute(…) всё работает прекрасно, но после внесения изменений в файл Input.inp и повторном запуске ShellExecute(…) ничего не изменяется – надо завершить работу облочки и снова начать всё с начала…
Прошу экспертов помочь разрешить мои проблемы. Заранее благодарен всем откликнувшимся и предложившим решение.
 |
Вопрос задал: Драганов Василий Михайлович (статус: Посетитель)
Вопрос отправлен: 25 февраля 2009, 21:16
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, Драганов Василий Михайлович!
Есть два предположения.
Ваша программа забывает закрыть файл Input.inp за собой - то есть вызывать CloseFile() для него. Либо по какому то стечению обстоятельств он не вызывается.
Вариант два. На тот момент, когда файл повторно редактируется, GRWAVE.EXE ещё не завершилась и "не отпустила файл" (а может причиной есть батник).
Можно сделать обходное решение. Для каждого нового расчета генерировать новую пару файлов, а старую удалять. И отказаться вообще от батника. Строка запуска преобразиться где то до такой
var num:integer = 0;
....
num := num+1;
ShellExecute(Self.Handle,'open',PChar('GRWAVE.EXE <Input'+inttostr(num)+'.inp
>Output'+inttostr(num)+'.out'),nil,nil,SW_HIDE);
Хотя можно обойтись без файла Output.out. И даже без входного файла. И самая большая проблема этого кода - что нет никакого ожидания завершения запущенной программы и вообще контроля деятельности.
Можно начать с изучения следующих статей (там есть и исходники, которые можно прикрутить)
http://delphiworld.narod.ru/base/stdin_stdout.html - много теории, но и исходники хорошие
http://delphiworld.narod.ru/base/seize_console_output.html
http://delphiworld.narod.ru/base/console_to_memo.html - готовая функция для захвата вывода консоли в мемо.
Но ведь никто не мешает читать в TStringList или на худой конец мемо сделать невидимым.... Или сделать его ReadOnly+настроить шрифты и как элемент дизайна...
А можно плюнуть на всё и написать нормально на делфи:)
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 25 февраля 2009, 22:29
Оценка за ответ: 5
|
Мини-форум вопроса
Всего сообщений: 13; последнее сообщение — 26 февраля 2009, 14:34; участников в обсуждении: 4.
|
Драганов Василий Михайлович (статус: Посетитель), 25 февраля 2009, 23:16 [#1]:
Вадим К спасибо за оперативно подготовленный ответ.
По первому Вашему варианту - кто должен закрыть файл. Я его не открываю и потому не могу закрыть.
Вариант второй - программа GRWAVE.EXE выполняется в консольном окне и очень быстро если вместо парметра SW_HIDE указать SW_NORMAL видно, когда программа завершает работу и закрывает консольное окно.
Есть подозрение, что виноват Run.bat, так как файл Input.inp допускает изменения после вызова приложения GRWAVE.EXE и сохранение с тем же именем...
Что касается предложенных исправлений в коде - попробую!
Большое спасибо за помощь.
|
|
Вадим К (статус: Академик), 26 февраля 2009, 00:21 [#2]:
а кто подготавливает input.inp?
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Драганов Василий Михайлович (статус: Посетитель), 26 февраля 2009, 08:04 [#3]:
Файл Input.inp имеет такой вид:
ANS 315
HSCALE 7.35
EPSLON 6
SIGMA 0.005
dmin 1
dmax 400
dstep 2
FREQ 0.5
HTT 100
HRR 10
IPOLRN 2
go
stop
и готовится мной, число параметров может быть как больше, так и меньше (отсутствующие заменяются внутренним умолчанием).
|
|
Вадим К (статус: Академик), 26 февраля 2009, 10:09 [#4]:
Этот файл готовиться в редакторе или Вашей программой. Если программой, то надо смотреть код, вот здесь скорее либо нет правильного закрытия файла, либо ещё какая то мелочь. Например, если в делфи открыть какой нибудь проект, а потом выполнить File-Close All, то с проводника удастся удалить все файлы проекта, а вот каталог - нет, пока делфи не будет закрыта либо не будет сменён каталог. Чувствую, что здесь что то близкое.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Драганов Василий Михайлович (статус: Посетитель), 26 февраля 2009, 10:30 [#5]:
Когда файл подготовлен вне программы, при первом вызове приложения все работает. Изменения из Дельфи выполняются так:
procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
ANS, EPSLON, IPOLRN, HSCALE, HTT, HRR, FREQ, SIGMA, dmin, dmax, dstep: String;
F1: TextFile;
s1:String;
begin
// Загрузить исходные данные из файла 'Input.inp'
AssignFile(F1, DFPath+'Input.inp');
ReWrite(F1);
s1 := 'ANS '+ StringGrid2.Cells[0,1];
WriteLn(F1, s1);
s1 := 'HSCALE '+ StringGrid2.Cells[1,1];
WriteLn(F1, s1);
s1 := 'EPSLON '+ StringGrid2.Cells[2,1];
WriteLn(F1, s1);
s1 := 'SIGMA '+ StringGrid2.Cells[3,1];
WriteLn(F1, s1);
s1 := 'dmin '+ StringGrid2.Cells[4,1];
WriteLn(F1, s1);
s1 := 'dmax '+ StringGrid2.Cells[5,1];
WriteLn(F1, s1);
s1 := 'dstep '+ StringGrid2.Cells[6,1];
WriteLn(F1, s1);
s1 := 'FREQ '+ StringGrid2.Cells[7,1];
WriteLn(F1, s1);
s1 := 'HTT '+ StringGrid2.Cells[8,1];
WriteLn(F1, s1);
s1 := 'HRR '+ StringGrid2.Cells[9,1];
WriteLn(F1, s1);
s1 := 'IPOLRN '+ StringGrid2.Cells[10,1];
WriteLn(F1, s1);
WriteLn(F1, 'go');
WriteLn(F1, 'stop');
CloseFile(F1);
end;
|
|
Вадим К (статус: Академик), 26 февраля 2009, 11:11 [#6]:
Всё похоже на правду. Тут я даже не знаю, что предложить. Если только запускаемая программа GRWAVE.EXE закрывается (ей никто не мешает висеть в памяти и удерживать файл).
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Amidamaru (статус: 4-ый класс), 26 февраля 2009, 11:24 [#7]:
А может использовать TStringList?
Создать его, записать в него, то что должно быть в файле Input.inp и потом сохранить спомощью SaveToFile :
procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
ANS, EPSLON, IPOLRN, HSCALE, HTT, HRR, FREQ, SIGMA, dmin, dmax, dstep: String;
F1: TextFile;
s1:String;
strs:TStringList;
begin
// Загрузить исходные данные из файла 'Input.inp'
strs:=TStringList.Create;
try
strs.Add('ANS '+ StringGrid2.Cells[0,1]);
strs.Add('HSCALE '+ StringGrid2.Cells[1,1]);
strs.Add('EPSLON '+ StringGrid2.Cells[2,1]);
strs.Add('SIGMA '+ StringGrid2.Cells[3,1]);
strs.Add('dmin '+ StringGrid2.Cells[4,1]);
strs.Add('dmax '+ StringGrid2.Cells[5,1]);
strs.Add('dstep '+ StringGrid2.Cells[6,1]);
strs.Add('FREQ '+ StringGrid2.Cells[7,1]);
strs.Add('HTT '+ StringGrid2.Cells[8,1]);
strs.Add('HRR '+ StringGrid2.Cells[9,1]);
strs.Add('IPOLRN '+ StringGrid2.Cells[10,1]);
strs.Add('go');
strs.Add('stop');
strs.SaveToFile(DFPath+'Input.inp');
finally
strs.Free;
end;
end;
|
|
Драганов Василий Михайлович (статус: Посетитель), 26 февраля 2009, 11:27 [#8]:
А можно узнать, "висит ли в памяти" завершившая работу программа? Если єто так, таки висит, то как ее удалить насильно?
|
|
Amidamaru (статус: 4-ый класс), 26 февраля 2009, 11:37 [#9]:
Вообще можно посмотреть это через Диспетчер Задач на вкладке Процессы. А если через приложение, то тут нужно искать все процессы, если найден нужный, получать его ProcessID затем открывать процесс и уничтожать... как это делается я не разбирался.
PS Но я не думаю что это както связано. Т.к. если вы закрываете оболочку, то это не знчит что закрывается запущенный GRWAVE.EXE
|
|
Вадим К (статус: Академик), 26 февраля 2009, 12:11 [#10]:
А зачем искать то, что не терялось? в приведённых мной примерах, дочерний процесс запускается и полностью контролируется.
А если было запущенно несколько родительских процессов, то надо будет ещё разбираться, кто чей дочерний.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Пупкин В В (статус: 2-ой класс), 26 февраля 2009, 14:12 [#11]:
а файл Input.inp при повторном запуске ShellExecute точно правильный? Не остались ли там артефакты при перезаписи поверх старых данных (если новые данные короче предыдущих).
|
|
Драганов Василий Михайлович (статус: Посетитель), 26 февраля 2009, 14:26 [#12]:
Нет, здесь можно не копать - во-первых при повторном запуске пока не изменялось число параметров, во-вторых содержание нового, сохраненного файла контролируется в поле Memo ...
|
|
Пупкин В В (статус: 2-ой класс), 26 февраля 2009, 14:34 [#13]:
просто подумалось что GRWAVE.EXE не может правильно обработать файл, нам же не известно как там все устроено. Даже например может в последней строке надо Write(F1, 'stop'); вместо WriteLn(F1, 'stop');
Но в любом случае блокирует ваша программа ведь при перезагрузке все ок, в противном случае еслиб висел процесс GRWAVE.EXE презагрузка вашей прог-ы ничего не далаб.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|