Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Работа с документами / 21 сообщений из 21, страница 1 из 1
08.09.2008, 17:06
    #35528244
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Есть таблица, в которой храниться содержимое файлов (каждый файл в отдельной
записи на SQL сервере).

В гриде на форме показвается наименование файла. Можно ли организовать
интерактивный показ содержимого выбраного файла, если заранее не известно,
какое приложение отвечает за работу с этим типом файлов?

Хотелось бы, чтобы работы с файлом (просмотр, редактирование) прооисходили в
пределах моей формы (оле), но как заставить олеконтрол понять, что работать
надо с файлом, который будет подсунут интерактивно?

Вообще возможно ли это?


PS Для отображения картинок есть контрол image, в который можно сунуть любую
картинку (не обязательно физический файл на диске). Хотелось бы что-то
наподобии, но с любым типом документов.

Так, например, можно страницу Excel встроить в документ Word, и Word внутри
себя покажет документ Excel.


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
08.09.2008, 17:38
    #35528321
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Через ShellExecute сделал. Содержимое файла можно посмотреть, изменить.



lcFileName=GETENV("TEMP")+'\'+SYS(3)+JUSTFNAME(Document.Naimen)

STRTOFILE(Document.Document, lcFileName)

DECLARE INTEGER ShellExecute IN SHELL32.DLL ;

INTEGER, STRING, STRING, STRING, STRING, INTEGER

? ShellExecute(0, "Open", lcFileName, NULL, NULL, 1)



Но отслеживать, что файл был закрыт, а потом еще проверить был ли он
изменен - слабо представляю как реализовать. Есть ли механизмы открыть файл
"внутри своей формы"?


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
08.09.2008, 18:08
    #35528401
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Word`овские файлы отследить, что они открыты по томы, что сам не могу
открыть их на запись.
Т.е. пока я не могу открыть эти файлы на запись - sleep(500). Как открыл -
обрабатывай, проверяй изменения.

Но чтука в том, что некороые типы файлов открываются "родными
просмоторщиками" только на чтение. Т.е. в то время, когда файл еще смотрят,
его можно не только открыть другим приложением, но и удалить. А это уже не
знаю как отследить.

Как вариант на форму повесить кнопочку "Когда закончите работать с файлом
нажми на меня, чтобы сохранить изменения". Но, боюсь пользователи будут
тыркать на нее когда только не лень (и зачастую раньше времени).


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
08.09.2008, 18:16
    #35528416
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Как узнать, что в данный момент файл открыт другой программой (хоть на
чтение хоть на запись)?


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.09.2008, 08:41
    #35528852
leaf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
если он кем то открыт - будет ошибка
вот ее обрабатывай
либо fopen()
...
Рейтинг: 0 / 0
09.09.2008, 08:47
    #35528863
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
> Автор: leaf
> если он кем то открыт - будет ошибка
> вот ее обрабатывай
> либо fopen()


Не факт. :(


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.09.2008, 08:56
    #35528875
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Galyamov RinatЧерез ShellExecute сделал. Содержимое файла можно посмотреть, изменить.

Попробуй GETOBJECT().

Galyamov RinatНо чтука в том, что некороые типы файлов открываются "родными
просмоторщиками" только на чтение. Т.е. в то время, когда файл еще смотрят,
его можно не только открыть другим приложением, но и удалить. А это уже не
знаю как отследить.

Некоторые проги (блокнот например) читают файл и закрывают, т.е. в процессе работы с файлом он закрыт, поэтому его можно даже удалить, но если пользователь его сохранит файл будет создан заново.
Можно попробовать по принципу WinRAR`а сделать. Он при запуске распаковывает во временный файл, а потом следит за файлом если файл изменился (дата-время, размер) то спрашивает "обновить файл в архиве"



Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку, в базе только имя файла. Открывать файл из папки и дальше следить за ним не надо. Если пользователь его сохранит, то он сохранится сразу куда надо.
...
Рейтинг: 0 / 0
09.09.2008, 10:01
    #35529003
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
> Можно попробовать по принципу WinRAR`а сделать. Он при запуске
> распаковывает во временный файл, а потом следит за файлом если файл
> изменился (дата-время, размер) то спрашивает "обновить файл в архиве"

А вот по какому принципу он отслеживает файл?
Не постоянно же он его опрашивает? Да и мусор за собой он сам подчищает.

> Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку,
> в базе только имя файла. Открывать файл из папки и дальше следить за ним
> не надо. Если пользователь его сохранит, то он сохранится сразу куда надо.

Думал над этим, но хочется избавиться от шары, в принципе - невозможно
отследить кто и когда изменения внес.


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.09.2008, 10:40
    #35529084
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Galyamov Rinat
> Можно попробовать по принципу WinRAR`а сделать. Он при запуске
> распаковывает во временный файл, а потом следит за файлом если файл
> изменился (дата-время, размер) то спрашивает "обновить файл в архиве"

А вот по какому принципу он отслеживает файл?
Не постоянно же он его опрашивает? Да и мусор за собой он сам подчищает.

Поизучал FileMon`ом. Похоже WinRAR следит не за файлом, а за приложением его открывшим и срабатывает на закрытие приложения. За приложением следить достаточно просто.
Например если открыть *.DOC из архива, поменять, сохранить, закрыть файл не закрывая ворда, то WinRAR файл даже не проверяет, но стоит закрыть Word так сразу WinRAR начинает вопросы задавать.

WinRAR создает отдельный поток внутри себя для ожидания, в фоксе такое не провернуть, фокс однопоточный. Разве что в таймере ADIR() делать периодически и с исходными данными сравнивать. Или WinAPI функцию FindFirstChangeNotification() задействовать. Она примерно то же самое делает.

Galyamov Rinat> Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку,
> в базе только имя файла. Открывать файл из папки и дальше следить за ним
> не надо. Если пользователь его сохранит, то он сохранится сразу куда надо.

Думал над этим, но хочется избавиться от шары, в принципе - невозможно
отследить кто и когда изменения внес.
Возможно отследить кто когда открывал, чтобы только через прогу открывали можешь запретить чтение содержимого папки, тогда просто руками открыть папку и найти нужный в ней файл будет невозможно.
...
Рейтинг: 0 / 0
09.09.2008, 10:53
    #35529122
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
>За приложением следить достаточно просто.

А вот с этого места, пожалуйста, поподробнее

>Разве что в таймере ADIR() делать периодически и с исходными данными
>сравнивать.
Если сравнивать дату - еще туда сюда, а если сравнивать по содержимому - то
засада.


> Или WinAPI функцию FindFirstChangeNotification() задействовать. Она
> примерно то же самое делает.
В любом случае - это поможет мне определиться, что файл был изменен (но не
обязательно закрыт, что тоже проблема).
А вот если пользователь посмотрел, закрыл приложение, но не сохранил
изменения - то я никогда не дождусь "FirstChange".
А мусор за собой почистить не помешает.


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

Если не найду приемлимых вариантов - придется копнуть в эту сторону.


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.09.2008, 11:47
    #35529289
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Galyamov Rinat
>За приложением следить достаточно просто.

А вот с этого места, пожалуйста, поподробнее
Есть WinAPI функция CreateToolhelp32Snapshot() с ее помошью можно получить список всех запущенных процессов. Следить примерно так:
1. Получить текущий список
2. Открыть файл. С помошью ShellExecute() например
3. Получить список, сравнить с п.1, новый процесс будет от проги обработчика файла.
4. Ждем завершения процесса с помошью WaitForSingleObject()

Там правда структур много, писать на фоксе муторно будет. Могу исходник на MS VC 6 дать, там список запущенных процессов выводится.

Есть один подвох серьезный, WinRAR тоже на нем попадается. Если запустить Ворд, затем открыть из WinRAR`а какой-нибудь *.DOC, то новый процесс не создается, файл открывается имеющимся вордом, поэтому WinRAR в этом случае изменение файла не замечает. Можешь проверить.

Galyamov Rinat>Разве что в таймере ADIR() делать периодически и с исходными данными
>сравнивать.
Если сравнивать дату - еще туда сюда, а если сравнивать по содержимому - то
засада.
Содержимое зачем сравнивать? Сохранил во временный файл, запомнил дату-время, если изменилась, то значит изменили файл. Тут надо другое отслеживать, если сначала твою прогу закрыли, а потом измененный файл сохранили, так он обратно в базу никогда не попадет.

Galyamov RinatА мусор за собой почистить не помешает.
Как вариант: всегда кидать все временные файлы в одну папку, смотреть на дату файла и удалять все файлы старше N дней.

Galyamov Rinat> Возможно отследить кто когда открывал, чтобы только через прогу
> открывали можешь запретить чтение содержимого папки, тогда просто руками
> открыть папку и найти нужный в ней файл будет невозможно.

Если не найду приемлимых вариантов - придется копнуть в эту сторону.
Тут можешь добавить хранение нескольких последних версий файла на случай если кто попортит файл. Перед открытием сравнивай последнюю копию и текущее состояние, если отличаются сначала делай копию, затем открывай на редактирование. А кто попортил можно отловить по дате файла и логу где открытие файла будет фиксироваться. По крайней мере для Word`а и Excel`я это точно сработает, т.к. двум разным пользователям один файл одновременно не открыть.
...
Рейтинг: 0 / 0
09.09.2008, 12:02
    #35529337
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Dima TЕсть WinAPI функция CreateToolhelp32Snapshot() с ее помошью можно получить список всех запущенных процессов.
Проблема в том, что это будет именно список процессов . А не приложений (файлов), запустивших этот процесс.

Например, если на машине есть два одинаковых приложения, но расположенных в разных директориях и оба они будут запущены одновременно, то в списке процессов отличить их друг от друга будет невозможно.

Несмотря на то, что в документации написано о том, что можно прочитать полный путь доступа до файла, запустившего процесс, но реально возвращается только и исключительно имя файла. Без пути доступа.

По крайней мере, у меня не получилось "выцарапать" полный путь доступа к процессу. Только и исключительно собственно имя файла, запустившего процесс.
...
Рейтинг: 0 / 0
09.09.2008, 12:16
    #35529392
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
ВладимирМНапример, если на машине есть два одинаковых приложения, но расположенных в разных директориях и оба они будут запущены одновременно, то в списке процессов отличить их друг от друга будет невозможно.
Элементарно сравнить ProcessID, даже у одного и того же приложения запущенного в нескольких экземплярах этот параметр отличается.

ВладимирМНесмотря на то, что в документации написано о том, что можно прочитать полный путь доступа до файла, запустившего процесс, но реально возвращается только и исключительно имя файла. Без пути доступа.

По крайней мере, у меня не получилось "выцарапать" полный путь доступа к процессу. Только и исключительно собственно имя файла, запустившего процесс.
Получить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)

Только в данном случае достаточно сравнить два массива ProcessID до запуска и после. И выявить тот который добавился. Проблема только в том что он может не добавиться, как я выше писал.
...
Рейтинг: 0 / 0
09.09.2008, 12:20
    #35529404
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Dima TПолучить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)
Я тоже так думал. А ты сам пробовал?
...
Рейтинг: 0 / 0
09.09.2008, 12:26
    #35529427
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Ясно. Решение задачи в итоге окажется очень сложным и неоправданно
запутанным.

Если склониться к хранению в шаре сервера, то есть еще одна проблема - когда
будет много фалов будут большие тормоза.

Придется, наверное, ограничивать список возможных документов для хранения.
И обрабатывать каждый тип документа своим OLE сервером.

Возможно, даже положить его на форму и прямо в ней открывать. Примеры такого
кто-нить видел?


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.09.2008, 12:27
    #35529429
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
ВладимирМ Dima TПолучить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)
Я тоже так думал. А ты сам пробовал?
Пробовал, результат в архиве с исходниками на MSVC6
Выводит список всех процессов с подробностями.

А пробовал чтобы написать проверку запущен ли какой-нибудь процесс из заданной папки. Там же в ListProcess.cpp функция IsWorkingPath(LPCTSTR pcszPath)
...
Рейтинг: 0 / 0
09.09.2008, 12:42
    #35529507
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Galyamov RinatЕсли склониться к хранению в шаре сервера, то есть еще одна проблема - когда
будет много фалов будут большие тормоза.
Наблюдал однажды автоматизацию хранения сертификатов отсканированных, в папке жило около 100 тысяч файликов с отсканированными бумажками, тормозило немного, но работало. Потом перестроили хранение в подпапках с ограничением кол-ва файлов на одну папку, тормоза прошли.

Проверять надо до какого кол-ва файлов не тормозит если непосредственно по имени файла обращаться. Дерево из подпапок соорудить, и ограничить не более N файлов и подпапок в одной папке например. И хранить путь к файлу относительно шары, что-то типа такого "SUBFOLDER001\SUBFOLDER123\MyFile.doc"
...
Рейтинг: 0 / 0
10.09.2008, 13:49
    #35531881
Galyamov Rinat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Т.к. других вариантов не нашел, решил ограничиться "известными" типами файлов (с последующим расширением списка).

Сделал слдеующее:

В клике кнопки "показать":
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
DO CASE

CASE INLIST(JUSTEXT(Document.Naimen), 'XLS')

lcFileName=GETENV("TEMP")+'\'+SYS( 3 )+JUSTFNAME(Document.Naimen)

STRTOFILE(Document.Document, lcFileName)

ThisForm.Pageframe1.Page2.AddProperty('Doc',CREATEOBJECT("Excel.Application"))

ThisForm.Pageframe1.Page2.Doc=ThisForm.Pageframe1.Page2.Doc.WorkBooks.Open(lcFileName)

ThisForm.Pageframe1.Page2.Doc.Parent.Visible = .T.

ThisForm.Timer1.Enabled=.t.

CASE INLIST(JUSTEXT(Document.Naimen), 'RTF', 'DOC')

lcFileName=GETENV("TEMP")+'\'+SYS( 3 )+JUSTFNAME(Document.Naimen)

STRTOFILE(Document.Document, lcFileName)

ThisForm.Pageframe1.Page2.AddProperty('Doc',CREATEOBJECT("Word.Application"))

ThisForm.Pageframe1.Page2.Doc=ThisForm.Pageframe1.Page2.Doc.Documents.Open(lcFileName)

ThisForm.Pageframe1.Page2.Doc.Parent.Visible = .T.

ThisForm.Timer1.Enabled=.t.

ENDCASE

В timer1.timer:

Код: plaintext
1.
2.
3.
4.
5.
IF !TYPE('ThisForm.Pageframe1.Page2.Doc.Parent')='O'
	WAIT WINDOW NOWAIT 'Надо сохранить файл'
	MESSAGEBOX('Надо сохранить файл')
	this.Enabled= .F.
ENDIF


Использую TYPE('ThisForm.Pageframe1.Page2.Doc.Parent'), а не VARTYPE(ThisForm.Pageframe1.Page2.Doc), т.к. VARTYPE(ThisForm.Pageframe1.Page2.Doc) возвращает "O" даже если сам объект уже разрушен. Приходится передернуть любое свойство объекта.


Насколько "некривой" подход? Есть мысли?
...
Рейтинг: 0 / 0
10.09.2008, 14:42
    #35532014
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Что будет если прогу раньше закроют чем файл?

Ни разу не пользовался, в SOLUTION увидел. Можно лист экселя (или документ ворда) прямо в форму вставить:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
THISFORM.addobject('oDoc','olecontrol','Excel.Sheet')
THISFORM.WindowState =  2 
THISFORM.oDoc.Height =  THISFORM.height -  40 
THISFORM.oDoc.Width =  THISFORM.width
THISFORM.oDoc.Top =  THISFORM.top
THISFORM.oDoc.Left =  THISFORM.left
THISFORM.oDoc.DocumentFile = lcFileName
THISFORM.oDoc.Visible =  .t.
THISFORM.oDoc.DoVerb(- 1 )
Только как туда твой файл подцепить не совсем понятно, в хэлпе на DoVerb() есть пример через промежуточный класс-обертку. Покопай, может еще варианты есть. С сохранением тоже не все понятно.
...
Рейтинг: 0 / 0
10.09.2008, 14:44
    #35532027
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Случайно попало:
Код: plaintext
THISFORM.oDoc.DocumentFile = lcFileName
Так не работает, ошибка "Property DocumentFile is Read-Only"
...
Рейтинг: 0 / 0
10.09.2008, 16:00
    #35532291
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с документами
Dima TСлучайно попало:
Код: plaintext
THISFORM.oDoc.DocumentFile = lcFileName
Так не работает, ошибка "Property DocumentFile is Read-Only"

http://forum.foxclub.ru/read.php?29,343196,343216#msg-343216
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Работа с документами / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]