Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2013.07.07;
Скачать: [xml.tar.bz2];

Вниз

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

 
Сергей из Самары   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.003 c
1-1307691044
Jakudza
2011-06-10 11:30
2013.07.07
Как получить данные из грида чужого окна?


2-1352803524
Павел Калугин
2012-11-13 14:45
2013.07.07
Подскажите как правильно работать с библиотеками BPL


2-1353101914
vasa777
2012-11-17 01:38
2013.07.07
checkbox в memo


3-1290592075
masterbloger
2010-11-24 12:47
2013.07.07
СУБД Cache + Delphi


15-1361735119
XXXXX
2013-02-24 23:45
2013.07.07
Создание класса в TRY/FINALLY.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский