У меня есть скрипт который обрабатывает закаченные doc файлы:
$word = new COM("word.application");
$word->Documents->Open($filename);
$word->Selection->Font->Name = 'Verdana';
$word->Selection->Font->Size = 8;
$word->Documents[1]->Save();
$word->quit();
Кто-нибуть знает как реализовать:
1. при выполнении Open не запускать АвтоМакросы (Если честно не знаю открываются они или нет, но недавно удалил тьму вирусов с сервака=)))
2. После безопасного открытия удалить все макросы из файла
3. Как видно из скрипта ворд запускается при каждом обращении к скрипту. Есть ли вариант не запускать новый, а обратиться к уже открытому экземпляру Ворда?(в сессию com-бъект сохранить нельзя, но если ворд не закрыть он продолжит висеть в памяти) При этом надо учитывать что скрипт может одновременно запускаться несколько раз, что бы не было конфликтов при обращении к одному и тому же экземпляру Ворда.
21 апреля 2008 в 22:04
Ну ясно, будем капать.=)) Еще раз большое спасибо!
21 апреля 2008 в 20:00
Эти беды мы пока не победили. У нас правда Word несколько в ином контексте "дёргается": будучи активированным внутри нашего приложения-контейнера. Но подобные ошибки иногда вываливаются, довольно бессистемно, прогресса по ним пока нет. Если будет продвижение – рад буду услышать как Вы это "вылечили"
21 апреля 2008 в 19:04
В общем сделал так. Каждый скрипт устанавливает в БД параметр, если он хочет занять ворд. Если параметр уже установлен, то ждет освобождения какое-то время. В общем все идет нормально. Переодически бывает, что одновременно оказываются запущенными 2 ворда. Не знаю откуда это. На всякий случай написал утилитку на С++ которая выкидывает их памяти всех вордов. Вызываю перед каждым освобождением параметра.
Дмитрий Гайдамович. Большой-большой респект за помощь.=)))
Единственная проблема – переодически выскакивают Exeption's:
1. Unable to lookup `Range': The object invoked has disconnected from its clients.
2. Unable to lookup `Range': Call was rejected by callee.
3. Unable to lookup `Range': The interface is unknown.
(Выскакивали они до того как я добавил killword)
Строка: $doc->Range->InsertFile($file);
Но док-файлы на которых это происходит спокойно обрабатываются на второй раз.
17 апреля 2008 в 0:04
Word фиговый в том плане, что он иногда пытается открывать окна с сообщениями об ошибках, или для подтверждения чего-либо, будучи запущенным в невидимом режиме, вместо того, чтобы генерировать нормальный OLE-exception. Как правило, в этом случае мы намертво встаём в модальном цикле, и закрыть окно мы тоже не можем, так как его нет, как ни странно это прозвучит.
Лучше взять Range у Document и делать InsertFile прямо у него, а про Selection забыть.
16 апреля 2008 в 19:04
В общем ситуация такая
Нашел статью //support.microsoft.com/kb/257757/ru
в которой микрософт рассказывает почему не следует делать с вордом то, что делаю я.=)) Судя по этой статье "залипания" ворда происходят во время появления каких-то ошибок(точнее сообщений об ошибках).
В общем решил создавать Word.Document. и делать вставку из файла. Это кстати решает проблему с макросами=) И ворд закрываеться сам по окончании работы скрипта.
Единственное что не понятно: что будет если 2 скрипта обращаются к одному и тому же $word->Selection:
$doc = new COM("Word.Document");
$word = $doc->Application;
{в этот момент запускается второй скрипт и выполняет предыдущие команды}
$word->Selection->InsertFile('C:\\file.doc');
// Тут идет модификация текста
$doc->SaveAs('C:\\file.doc');
$doc->Close();
Получается вставка произойдет не в тот документ, так как обе $word->Selection будут указывать на одно и тоже выделение.
PS Я понял про прокси процесс и контроль монопольного доступа. Только на php это не так просто сделать, учитывая уже существующую модель приложения. Но если не останется вариантов, то так и сделаю.
14 апреля 2008 в 18:03
WINWORD.EXE склонен "залипать" в памяти, факт. И порой источник "размножения" winword не совсем ясен.Для борьбы с этим явлением можно применять следующие способы. 1) После отпускания всех объектов, когда необходимость в Word-е отпала – не забывать делать Application.Quit(). Часто эта веточка хотя и предусмотрена в программе, однако не выполняется. К тому же данный подход не спасает, если программа, использующая Word, завершается аварийно. А это в нашем неидеальном мире – распространённое явление. Тогда приходится делать вариант 2): Proxy-процесс. Идея в следующем. Ссылку на созданный Word.Applicatoin получаем не непосредственно от подсистемы COM, а создаём программу, которая создаёт этот объект по требованию, и отдаёт нам ссылку на созданный объект. Кроме того, что она может помочь в предотвращении повторного создания, эта программа также делает следующее: она "следит" за состоянием основного процесса, и когда он "умирает" – то "убивает" тот Word, который был закреплён за ним. При этом неважно, завершается ли основной процесс штатно или аварийно – winword будет выгружен из памяти по-любому.
Да, и ещё. Если доступ к Word происходит из нескольких потоков – то лучше делать это в критической секции, куда "запускается" единственный поток. В противном случае будут глюки, мы это проходили.
14 апреля 2008 в 14:01
Выкинул из памяти все процессы WINWORD.EXE Теперь все стало сново работать. Добавил логирование исключений, в файл. теперь буду ждать когда появится ошибка сново.
Интересно что ошибка добавляеться в php-errors.log файл не сразу, а примерно через 4 часа.
И еще: В системном логере приложений появилось дикое количество ошибок типа:
Event Type:Error
Event Source:Microsoft Office 11
Event Category:None
Event ID:2001
Date:10.04.2008
Time:20:41:15
User:N/A
Description:
Rejected Safe Mode action : Microsoft Office Word.
For more information, see Help and Support Center at //go.microsoft.com/fwlink/events.asp.
но по времени они не очень совпадают с ошибками в php_errors.log
14 апреля 2008 в 11:05
Отладчика для COM нету, есть всякие утилиты, типа oleview, и т.п. – в популярных книжках по COM они перечисляются. COM-объекты "живут" в обычных dll- и exe-серверах, поэтому их отладка ничем не отличается от отладки обычных программ. Но не думаю, что отладчик здесь поможет. Разве что у Вас есть исходники Word:)) Нужно разбираться, что там за ошибка при старте Word. Он вообще-то запускается, сам по себе?
14 апреля 2008 в 11:01
А есть какой-нибуть отладчик для COM? что бы можно было видеть что там происходит.
С какого-то перепугу скрипт стал выдавать ошибку: Failed to create COM object `word.application': Server execution failed
14 апреля 2008 в 8:04
Ок. Спасибо!!!=))
13 апреля 2008 в 20:04
Document.VBProject
13 апреля 2008 в 10:03
А можно поподробнее про второй пункт. Как это на VBA можно сделать?
13 апреля 2008 в 1:03
1. В настройках безопасности Word выставляется высокий уровень.
2. Если в настройках безопасности разрешён доступ к VB Project – то делается тоже несложно.
3. Как в php – не знаю, честно говоря, но в самом COM-е наряду с функцией создания объекта имеется функция подключения к уже запущенному объекту. Обычно её выводят в скрипты. Например, в VB (VBA) имеются CreateObject и GetObject для этих двух видов получения ссылки на объект. Вариант N 2 – создавать не Word.Application, а другой, например, Word.Document, и, к примеру, уже в него вставлять из файла. В последнем случае Word также не будет запущен повторно.
12 апреля 2008 в 23:02
Еще желательно что бы при открытии ворд не делал запрос на проверку на вирусы. Для ускорения открытия файла.