Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.07.07;
Скачать: CL | DM;

Вниз

Блокировка запущенной программы из программы   Найти похожие ветки 

 
Сергей из Самары   (2011-06-02 12:26) [0]

Есть такая задача:
В БД хранится некий вордовский документ. Его нужно извлечь из базы, открыть. Если в нем внесена правка, сохранить и снова загрузить в базу. Понятно, что пока файл открыт ни другой пользователь не может получить доступ к этому файлу в базе, ни сам пользователь не должен работать в в программе. То есть программа должна висеть, пока человек либо не закроет файл без сохранения, либо сохранит его и тоже закроет.

Реализовал я механизм следующим образом:

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 пролетает махом. В результате программа не блокируется и выполняется дальше. Даже если в файл внесены изменения в базу он записан не будет. Подскажите, как можно решить эту проблему? Возможно ли как-то, если на компе запущены другие вордовские процессы, блокировать и их?Или проблему можно решить иначе?


 
QAZ   (2011-06-02 12:58) [1]

а зачем вообще эти файлы хранить в бд ? приэтом открывать с диска? и сохранять на дскже?


 
Сергей из Самары   (2011-06-02 13:16) [2]

Есть некоторые шаблоны документов с готовым текстом. По тексту разбросаны маркеры, которые меняются при первой загрузке на данные из БД. Открывается заполненный документ, который пользователь должен внести еще дополнительные изменения: дописать то, что нет в БД, внести свои примечания и т.д. Вот этот документ и должен храниться в БД. При этом он должен быть доступен для редактирования. То есть его всегда должно быть можно достать, что-то в нем отредактировать и снова загрузить в БД.


 
Юрий Зотов ©   (2011-06-02 13:46) [3]

При открытии документа заблокировать запись в таблице, при сохранении в БД - разблокировать?

Но непонятно - почему документ не может редактироваться двумя юзерами одновременно? Кто последний запишет его обратно в БД - тот и прав. Это обычная практика, и не только для BLOB-полей.


 
Сергей из Самары   (2011-06-02 14:00) [4]

При открытии документа запись переходит в состоянии update. Пока с ней работает пользователь больше никто не сможет ничего там изменить. Вопрос не в этом. Вопрос в том, что программа, из которой вызывается ворд с документом, должна блокироваться, пока пользователь не закроет этот самый документ. До тех пор, пока на компьютере не запущен ни один вордовский файл - все работает. Но стоит открыть хоть один и блокировка перестает работать, а потому не отслеживается момент закрытия документа и не сохраняются внесенные в него изменения. Вот этот момент и надо победить. И пока я даже не знаю в какую сторону копать.


 
QAZ   (2011-06-02 14:13) [5]

копать в сторону с которой у тебя в шаблоне маркеры заменяются


 
Сергей из Самары   (2011-06-02 14:29) [6]

А это тут причем? Тут все в порядке и они меняются всегда и везде и без ошибок. Причем делается это один раз при загрузке шаблона. В базе документ хранится уже без всяких маркеров. И открывается повторно без них. Проблема в том, что при открытом вордовом документе не срабатывается вот эта часть:

while (WaitForSingleObject(p.hProcess, 100) = WAIT_TIMEOUT) do  
       Application.ProcessMessages;


 
sniknik ©   (2011-06-02 14:34) [7]

а что возвращает вместо WAIT_TIMEOUT?


 
sniknik ©   (2011-06-02 14:38) [8]

Удалено модератором


 
Сергей из Самары   (2011-06-02 14:55) [9]

WAIT_TIMEOUT = 258
WaitForSingleObject(p.hProcess, 100) = 258

Вот это и непонятно В одном случае все работает, в другом пролетает без задержки


 
Anatoly Podgoretsky ©   (2011-06-02 15:13) [10]

> Сергей из Самары  (02.06.2011 14:00:04)  [4]

Редактирование конечно Вордом?
Так он изначально предназначен для редактирования любого количества
документов и это не изменить.


 
Anatoly Podgoretsky ©   (2011-06-02 15:13) [11]

> Сергей из Самары  (02.06.2011 14:00:04)  [4]

Надо издать инструкцию по работе с этой корявой программой и под роспись.


 
QAZ   (2011-06-02 15:14) [12]


> А это тут причем?

ну вот как ты объщаешся с вордом чтобы заменить маркеры


 
Anatoly Podgoretsky ©   (2011-06-02 15:14) [13]

Удалено модератором


 
Сергей из Самары   (2011-06-02 15:32) [14]

Вордом. Пользователи не хотят отказываться от его функционала.
И что, совсем никак эту проблему не решить?


 
Сергей из Самары   (2011-06-02 15:36) [15]


> стати странно... нужна блокировка программы пока не вышли
> из процесса, а тут таймаут добавлен и ProcessMessages...
>  

Это уже в процессе экспериментов накрутилось. Изначально было только:
WaitForSingleObject(p.hProcess, Infinite)


> Надо издать инструкцию по работе с этой корявой программой
> и под роспись.

Если бы я хотел оставить как есть, так бы и сделал. Но я и пытаюсь решить эту пролему.


 
sniknik ©   (2011-06-02 15:43) [16]

Удалено модератором


 
sniknik ©   (2011-06-02 16:04) [17]

вот, весь код
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, в событии "на выход" прописываем то что выше показано.
все.


 
Inovet ©   (2011-06-02 16:16) [18]

Удалено модератором


 
Anatoly Podgoretsky ©   (2011-06-02 16:40) [19]

Удалено модератором


 
Сергей из Самары   (2011-06-02 17:59) [20]

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); вылетает ошибка, что процесс не может получить доступ к файлу, так как он занят другим приложением если я внесу изменения в документ, нажму закрыть документ и на вопрос хочу ли я сохранить документ отвечу "Да". Если я перед закрытием нажму на "сохранить", то все проходит без проблем. При этом, если я сохранение в базу комменчу, то удаление файла (которое стоит сразу после записи в базу) происходит без проблем и файл оказывается никем не занят.


 
Сергей из Самары   (2011-06-02 18:29) [21]

Кажется, разобрался сам. Спасибо за помощь.



Страницы: 1 вся ветка

Текущий архив: 2013.07.07;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.008 c
15-1361396205
TUser
2013-02-21 01:36
2013.07.07
Артиллерия


1-1307691044
Jakudza
2011-06-10 11:30
2013.07.07
Как получить данные из грида чужого окна?


2-1352981138
Anariem
2012-11-15 16:05
2013.07.07
Timer


15-1361392203
Юрий
2013-02-21 00:30
2013.07.07
С днем рождения ! 21 февраля 2013 четверг


1-1308294107
abwabw
2011-06-17 11:01
2013.07.07
Как изменить размер кнопок у ScrollBar-а?