Здраствуйте!
Подскажите пожалуйста как решить следующую проблему:
я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы:
1. Файл ещё не сформирован полностью
2. Он вообще заблокирован внешней программой
Для решения этих проблем, я решил завести таймер и каждые 100 м.сек обращаться к файлу для проверки его размера. Но при попытке обратится к нему с помощью функции
Reset(f) возникает ошибка. Вобщем не могли бы Вы мне подсказать, каким образом мне можно приостановить алгоритм выполнения моей программы, до тех пор, пока внешняя программа не закончит свою работу и не разблокирует файл?
Re: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Здраствуйте! AR>Подскажите пожалуйста как решить следующую проблему: AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы: AR>1. Файл ещё не сформирован полностью AR>2. Он вообще заблокирован внешней программой AR>Для решения этих проблем, я решил завести таймер и каждые 100 м.сек обращаться к файлу для проверки его размера. Но при попытке обратится к нему с помощью функции AR>Reset(f) возникает ошибка. Вобщем не могли бы Вы мне подсказать, каким образом мне можно приостановить алгоритм выполнения моей программы, до тех пор, пока внешняя программа не закончит свою работу и не разблокирует файл?
Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.
Здравствуйте, AReal, Вы писали:
AR>Здраствуйте! AR>Подскажите пожалуйста как решить следующую проблему: AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы:
Здравствуйте, Danchik, Вы писали: D>Я так понял програма что то делает, создает файл завершает выполнение. Так?
Да, совершенно верно. Программа проверяет ЭЦП в документах, отчёт о проверке выводит в файл. Мне нужно потом обратиться к этому файлу и определить фамилии сотрудников, ЭЦП которых имеется в этих документах. Сама моя программа запускается переодически, и проверяет на наличие в некоторой папке документов, проверить на ЭЦП которые необходимо. Я ни как не могу определить момента, когда внешняя программа завершила свою работу. Пробовал ставить метки, шо мол, если размер файла не изменился, то вернуться в начало, но толку нет — программа виснит. А в другой раз,решил поставить таймер. Априорно вычислил, что на проверку одного документа уходит примерно 6 сек. после этого внешняя программа выгружается из деспетчера задач, и к файлу который она сформировала, можно спокойно обращаться. Проблема в том, что я не знаю сколько документов предлагается внешней программе для проверки в единицу времени. Потому использовать таймер не имеет смысла. Время так же увеличивается, пичём не линейно, если в файле имеется ЭЦП сразу нескольких сотрудников.
Здравствуйте, BlackEric, Вы писали: BE>Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.
А как мне узнать когда она уйдёт?
Re[3]: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Здравствуйте, BlackEric, Вы писали: BE>>Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась. AR>А как мне узнать когда она уйдёт?
Когда не будет генериться исключение при попытке открытия файла.
Здравствуйте, Rius, Вы писали:
R>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события.
А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.
Re[3]: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Здравствуйте, Danchik, Вы писали: D>>Я так понял програма что то делает, создает файл завершает выполнение. Так? AR>Да, совершенно верно. Программа проверяет ЭЦП в документах, отчёт о проверке выводит в файл. Мне нужно потом обратиться к этому файлу и определить
Ну, можно придумать несколько вариантов и их комбинаций.
1) Сканируем список процессов — одна процедура из jclSysUtils (JEDI). Как только имя процесса ушло из списка — пробуем достучаться к файлу данных...
2) Открываем файл в режиме fmShareDenyNone (для Reset() — читаем о переменной FileMode) и читаем кусками. Как только размер изменился (хоть по таймеру, хоть по эвенту от файловой системы, хоть FindFirst/FindNext проверяем) — читаем следующий кусок. Главное чтобы внешняя прога не открывала файл экслюзивно (fmShareDenyRead).
3) Если нам не удалось доступиться к файлу/прочитать данные — уходим в Sleep(). И пользователю рисуем окошко — мол, работаю.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[5]: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Здравствуйте, Rius, Вы писали:
R>>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события. AR>А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.
Запускаете прогу функцией CreateProcess с параметрами (см. msdn или google) и ждёте пока она вернёт управление. Если ваша прога в это время повисает, попробуйте запускать из другого потока.
Re[5]: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Здравствуйте, Rius, Вы писали:
R>>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события. AR>А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.
Вот примерчик:
procedure ExecAndWait (FileName : string);
var
ProcessInfo : TProcessInformation;
StartupInfo : TStartupInfo;
ExecString : string;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
with StartupInfo do begin
cb := sizeof(StartupInfo);
lpReserved := nil;
lpDesktop := nil; {inherit}
lpTitle := nil;
dwFlags := STARTF_USESHOWWINDOW; {Tis means it should be used wShowWindow}
wShowWindow := SW_HIDE;
cbReserved2 := 0;
lpReserved2 := nil;
end;
ExecString := FileName;
if not CreateProcess( nil,
PChar(ExecString),
nil,
nil,
false,
NORMAL_PRIORITY_CLASS,
nil,
nil,
StartupInfo,
ProcessInfo)
then
RaiseLastOSError;
case WaitForSingleObject(ProcessInfo.hProcess, 10 * 60 * 1000 {10 min}) of
WAIT_TIMEOUT : raise Exception.Create ('Process timed out.');
WAIT_FAILED : raise Exception.Create ('Process filed')
end;
end;
Re: Как приостановить выполнение алгоритма программы?
Здравствуйте, AReal, Вы писали:
AR>Подскажите пожалуйста как решить следующую проблему: AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно.
мне неясно, консольное это приложение или GUI.
выложил здесь пример ожидания завершения программы на случай GUI — разбирайся, спрашивай. test.wait.process.7z
в случае консольного приложения задача еще проще
function StartProcess(const CommandLine : String; ShowFlag : Word) : THandle;
var
si : TStartupInfo;
pi : TProcessInformation;
rc : BOOL;
begin
FillChar(si, SizeOf(si), 0);
FillChar(pi, SizeOf(pi), 0);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := ShowFlag;
rc := CreateProcess(nil, PChar(CommandLine), nil, nil, False, 0, nil, nil, si, pi);
if not rc then
begin
Result := 0;
Exit;
end;
CloseHandle(pi.hThread);
Result := pi.hProcess;
end;
...
hProcess := StartProcess('app.exe', SW_SHOWNORMAL);
if (hProcess = 0) then ; // уходим, процесс не запущен
dwWait := WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess); // не забываем освобождать хендлыif (dwWait = WAIT_OBJECT_0) then// успешно дождалисьelse// какая-то ошибка
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Windows XP 5.1.2600.131072 ... Cannabis Corpse — Addicted to Hash in a Tin