Форум: "Начинающим";
Текущий архив: 2008.07.20;
Скачать: [xml.tar.bz2];
ВнизКак заставить программу ждать, пока выполнится вызванная другая? Найти похожие ветки
← →
light-blr (2008-06-19 01:37) [0]Здравствуйте!
Никогда не работала с батниками, а тут пришлось.
В общем, у меня есть несколько *.bat-файлов, которые должны вызываться поочерёдно. Первый формирует список файлов, который модифицируется моей программой, затем сразу вызывается второй, который по этому списку формирует ещё один, и он не должен вызваться раньше, чем сформируется первый список.
Поскольку все они лезут в интернет за данными, время исполнения у них всегда разное. Я пробовала написать вот так:
Winexec(pchar("mylinks.bat"),sw_shownormal);
while not (fileexists("ok.html"))do;
т.е. пока батник не создал файл, моя программа должна бездействовать. Но после создания файл должен быть наполнен данными (по весу каждый раз разными), а не успевает.
Я не могу поставить никакого таймера, потому что закачка данных из инета - дело сугубо индивидуальное, и не могу проверять, достаточно ли уже данных в файле, чтобы начать с ним работать. Единственный выход, который мне видится - дождаться закрытия окна bat-файла. Но вот как это сделать - не знаю.
Пожалуйста, подскажите или как это сделать, или какой-нибудь ещё обходной путь, который я не заметила...
← →
Servy © (2008-06-19 02:16) [1]1. Использовать CreateProcess (WinExec судя по хелпу оставлен лишь для обратной совместимости, и вызов CreateProcess все-равно происходит, только Handle процесса сразу закрывается) и потом WaitForSingleObject. Путь более правильный, но требует некоторого напряжения мысли и умения прочитать хелп/нагуглить пример.
2. Сигнализировать о завершении нужных действий из батника. Например, когда все готово, создать файл "alldone.txt", существование которого и проверять в программе. За применение таких методов в чем-то более-менее серьезном следует нещадно карать, но для какой-нибудь лабы сойдет, усилий мозга требует значительно меньше.
← →
light-blr (2008-06-19 02:35) [2]Да не, не лаба, их-то я всегда сама делала. Для себя программу пишу.
Второй путь я сразу отметила и пробовала... Но, к сожалению, он почему-то не срабатывает. Т.е. вместо того чтобы выполниться первой строчке и потом начать выполняться второй, батник почему-то выполняет их почти одновременно.
А есть ли какой-нибудь таймер для консольного приложения? Если за 5 минут в файл не записалось ни байта - можно считать, что он уже готов. Тут ведь проблема не в быстродействии, а чтобы вообще в принципе хоть как-то работало и выполняло свои функции. Для оконного приложения таймер знаю, для консольного - нет...
За совет №1 спасибо, буду копать в этом направлении.
← →
Servy © (2008-06-19 08:01) [3]> Т.е. вместо того чтобы выполниться первой строчке и потом
> начать выполняться второй, батник почему-то выполняет их
> почти одновременно.
Загадочно все). Вот у меня он выполняет все строго последовательно, пока блокнот не закрою, файла не создает. Что я делаю не так?notepad.exe
echo Hate this cruel world > done.txt
> А есть ли какой-нибудь таймер для консольного приложения?
> Если за 5 минут в файл не записалось ни байта - можно считать,
> что он уже готов.
Вот вам пример ожидания пяти минут.uses
Windows;
var
Start, Finish: Cardinal;
const
Delay = 5 * 60 * 1000; // 5 минут
// ...
// тут надо ждать 5 минут
Start := GetTickCount;
Finish := Start;
while (Finish - Start < Delay) do
begin
Sleep(100);
Finish := GetTickCount;
end;
// 5 минут закончились
Про "записалось ни байта" - если охота проверяйте сами :).
> За совет №1 спасибо, буду копать в этом направлении.
Успехов.
← →
Anatoly Podgoretsky © (2008-06-19 08:48) [4]> light-blr (19.06.2008 2:35:02) [2]
Запускай в батнике без ключевого слова start тогда вторая строчка не начнет выполняться пока не выполнится первая.
← →
palva © (2008-06-19 09:10) [5]Можно написать еще один батник, который будет вызывать батники последовательно при помощи ключевого слова call
← →
Ega23 © (2008-06-19 10:24) [6]Игорь Шевченко как-то мне такую дал:
function RunAndWait (const ExeName, ParamString: string;
QuoteParams: Boolean = true): Integer;
var
ShellInfo: TShellExecuteInfo;
ExitCode: DWORD;
begin
ShellInfo.cbSize := SizeOf(ShellInfo);
ShellInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
ShellInfo.Wnd := HWND_DESKTOP;
ShellInfo.lpVerb := "open";
ShellInfo.lpFile := PChar(ExeName);
if QuoteParams then
ShellInfo.lpParameters := PChar("""+ParamString+""")
else
ShellInfo.lpParameters := PChar(ParamString);
ShellInfo.lpDirectory := PChar(ExtractFilePath(ExeName));
ShellInfo.nShow := SW_HIDE;
if not ShellExecuteEx(@ShellInfo) then
RaiseLastOSError;
if ShellInfo.hProcess <> 0 then
try
WaitForSingleObjectEx(ShellInfo.hProcess, INFINITE, false);
GetExitCodeProcess(ShellInfo.hProcess, ExitCode);
Result := ExitCode;
finally
CloseHandle(ShellInfo.hProcess);
end
else
Result := -1;
end;
← →
Viktorious © (2008-06-19 10:27) [7]Вот вам пример с CreateProcess:
var inf:TProcessInformation;
sInfo:TStartupInfo;
begin
FillChar(sInfo,sizeof(sInfo),0);
sInfo.cb:=sizeof(sInfo);
sInfo.wShowWindow:=SW_NORMAL;
CreateProcess(nil,"1.bat",nil,nil,false,CREATE_DEFAULT_ERROR_MODE or
NORMAL_PRIORITY_CLASS,nil,nil,sInfo,Inf);
WaitForSingleObject(Inf.hProcess,INFINITE);
end;
← →
Юрий Зотов © (2008-06-19 10:50) [8]> Viktorious © (19.06.08 10:27) [7]
1. Не хватает IF и двух CloseHandle.
2. Заполнение sInfo.wShowWindow и указание ненулевого флага - лишние.
← →
Sapersky (2008-06-19 15:19) [9]Вряд ли это пригодится автору вопроса, просто на заметку: WaitForSingleObject будет ждать завершения конкретно запускаемого процесса, но не процессов, которые он запустит дополнительно (некоторые инсталляторы так делают). Для ожидания всех, включая порождённые, можно использовать Job Objects.
← →
Anatoly Podgoretsky © (2008-06-19 16:37) [10]> Sapersky (19.06.2008 15:19:09) [9]
Если инсталятор не ждет, то и батнику ни к чему.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.07.20;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.043 c