![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Блокировка запущенной программы из программы [D7, WinXP]
Сергей из Самары © (2011-06-02 12:26:00)Есть такая задача:
В БД хранится некий вордовский документ. Его нужно извлечь из базы, открыть. Если в нем внесена правка, сохранить и снова загрузить в базу. Понятно, что пока файл открыт ни другой пользователь не может получить доступ к этому файлу в базе, ни сам пользователь не должен работать в в программе. То есть программа должна висеть, пока человек либо не закроет файл без сохранения, либо сохранит его и тоже закроет.
Реализовал я механизм следующим образом:
time_start := GetFileDate(fname); //Получаем время создания файла
FillChar( Si, SizeOf( Si ) , 0 );
with Si do
begin
cb := SizeOf( Si);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_SHOW;
end;
wp:= '"'+Form1.word_p+'" '+fname; //путь к ворду и параметр (имя файла)
Form1.WindowState:=wsminimized;
if Createprocess(nil, Pchar(wp), nil, nil,false,
CREATE_DEFAULT_ERROR_MODE, nil, nil, si, p) //запускаем
then begin
CloseHandle(p.hThread);
ShowWindow(Form1.Handle, SW_HIDE);
while (WaitForSingleObject(p.hProcess, 100) = WAIT_TIMEOUT) do //пока программа открыта, доступа к основной программе нет
Application.ProcessMessages;
CloseHandle(p.hProcess);
ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
end;
Form1.WindowState:=wsMaximized;
time_fin := GetFileDate(fname); //получаем время изменения файла
if Form5.Tag = 1 then begin //индикатор (файл можно просто открыть для просмотра, тогда его не нужно сохранять в базе, даже если в него внесли изменения
If time_start <> time_fin then //проверяется вносили ли в файл изменения, если да, то сохраняем в файл
begin
DBm.Priem.Edit;
DBm.PriemPROTOKOL_BL.Clear;
DBm.PriemPROTOKOL_BL.LoadFromFile(fname);
DBm.Priem.Post;
end;
end;
DeleteFile(fname); //удаляем сам файл с диска
Все работает, все проверяется... до тех пор, пока не запущен как какой-либо другой вордовский файл, совершенно посторонний. Если запущен ворд, то WaitForSingleObject пролетает махом. В результате программа не блокируется и выполняется дальше. Даже если в файл внесены изменения в базу он записан не будет. Подскажите, как можно решить эту проблему? Возможно ли как-то, если на компе запущены другие вордовские процессы, блокировать и их?Или проблему можно решить иначе?
Сергей из Самары (2011-06-02 18:29:00) [1]Кажется, разобрался сам. Спасибо за помощь.
Сергей из Самары (2011-06-02 17:59:00) [2]sniknik
Спасибо. Кажется, получается. Только один вопрос:
Я здесь
procedure TForm1.WordApplication1Quit(Sender: TObject);
begin
Enabled:= true;
end;
Еще прописываю загрузку файла в базу после закрытия:
Enabled:= true;
DBm.Priem.Edit;
DBm.PriemPROTOKOL_BL.Clear;
DBm.PriemPROTOKOL_BL.LoadFromFile(FilNm);
DBm.Priem.Post;
DeleteFile(FilNm);
Так вот, при закрытии в этом месте: DBm.PriemPROTOKOL_BL.LoadFromFile(FilNm); вылетает ошибка, что процесс не может получить доступ к файлу, так как он занят другим приложением если я внесу изменения в документ, нажму закрыть документ и на вопрос хочу ли я сохранить документ отвечу "Да". Если я перед закрытием нажму на "сохранить", то все проходит без проблем. При этом, если я сохранение в базу комменчу, то удаление файла (которое стоит сразу после записи в базу) происходит без проблем и файл оказывается никем не занят.
Anatoly Podgoretsky (2011-06-02 16:40:00) [3]Удалено модератором
Inovet (2011-06-02 16:16:00) [4]Удалено модератором
sniknik (2011-06-02 16:04:00) [5]вот, весь код
procedure TForm1.Button1Click(Sender: TObject);
begin
Enabled:= false;
WordApplication1.Connect;
WordApplication1.Visible:= true;
//открыть нужный файл сам допишешь
end;
procedure TForm1.WordApplication1Quit(Sender: TObject);
begin
Enabled:= true;
end;
в дизайне кладем на форму TWordApplication, ставим у свойства ckNewInstance, в событии "на выход" прописываем то что выше показано.
все.
sniknik (2011-06-02 15:43:00) [6]Удалено модератором
Сергей из Самары (2011-06-02 15:36:00) [7]
> стати странно... нужна блокировка программы пока не вышли
> из процесса, а тут таймаут добавлен и ProcessMessages...
>
Это уже в процессе экспериментов накрутилось. Изначально было только:
WaitForSingleObject(p.hProcess, Infinite)
> Надо издать инструкцию по работе с этой корявой программой
> и под роспись.
Если бы я хотел оставить как есть, так бы и сделал. Но я и пытаюсь решить эту пролему.
Сергей из Самары (2011-06-02 15:32:00) [8]Вордом. Пользователи не хотят отказываться от его функционала.
И что, совсем никак эту проблему не решить?
Anatoly Podgoretsky (2011-06-02 15:14:00) [9]Удалено модератором
QAZ (2011-06-02 15:14:00) [10]
> А это тут причем?
ну вот как ты объщаешся с вордом чтобы заменить маркеры
Anatoly Podgoretsky (2011-06-02 15:13:00) [11]> Сергей из Самары (02.06.2011 14:00:04) [4]
Надо издать инструкцию по работе с этой корявой программой и под роспись.
Anatoly Podgoretsky (2011-06-02 15:13:00) [12]> Сергей из Самары (02.06.2011 14:00:04) [4]
Редактирование конечно Вордом?
Так он изначально предназначен для редактирования любого количества
документов и это не изменить.
Сергей из Самары (2011-06-02 14:55:00) [13]WAIT_TIMEOUT = 258
WaitForSingleObject(p.hProcess, 100) = 258
Вот это и непонятно В одном случае все работает, в другом пролетает без задержки
sniknik (2011-06-02 14:38:00) [14]Удалено модератором
sniknik (2011-06-02 14:34:00) [15]а что возвращает вместо WAIT_TIMEOUT?
Сергей из Самары (2011-06-02 14:29:00) [16]А это тут причем? Тут все в порядке и они меняются всегда и везде и без ошибок. Причем делается это один раз при загрузке шаблона. В базе документ хранится уже без всяких маркеров. И открывается повторно без них. Проблема в том, что при открытом вордовом документе не срабатывается вот эта часть:
while (WaitForSingleObject(p.hProcess, 100) = WAIT_TIMEOUT) do
Application.ProcessMessages;
QAZ (2011-06-02 14:13:00) [17]копать в сторону с которой у тебя в шаблоне маркеры заменяются
Сергей из Самары (2011-06-02 14:00:00) [18]При открытии документа запись переходит в состоянии update. Пока с ней работает пользователь больше никто не сможет ничего там изменить. Вопрос не в этом. Вопрос в том, что программа, из которой вызывается ворд с документом, должна блокироваться, пока пользователь не закроет этот самый документ. До тех пор, пока на компьютере не запущен ни один вордовский файл - все работает. Но стоит открыть хоть один и блокировка перестает работать, а потому не отслеживается момент закрытия документа и не сохраняются внесенные в него изменения. Вот этот момент и надо победить. И пока я даже не знаю в какую сторону копать.
Юрий Зотов (2011-06-02 13:46:00) [19]При открытии документа заблокировать запись в таблице, при сохранении в БД - разблокировать?
Но непонятно - почему документ не может редактироваться двумя юзерами одновременно? Кто последний запишет его обратно в БД - тот и прав. Это обычная практика, и не только для BLOB-полей.
Сергей из Самары (2011-06-02 13:16:00) [20]Есть некоторые шаблоны документов с готовым текстом. По тексту разбросаны маркеры, которые меняются при первой загрузке на данные из БД. Открывается заполненный документ, который пользователь должен внести еще дополнительные изменения: дописать то, что нет в БД, внести свои примечания и т.д. Вот этот документ и должен храниться в БД. При этом он должен быть доступен для редактирования. То есть его всегда должно быть можно достать, что-то в нем отредактировать и снова загрузить в БД.