Lotus падает при работе с Com

  • Автор темы D!m@n
  • Дата начала
D

D!m@n

#1
Добрый день!

Вот такая эпидерсия:
Есть агент. Работает на клиенте. Его задача - взять из RichTextItem'а аттач, выгрузить на диск и распознать с помощью MODI.
Вот фрагмент кода, использующих распознавалку:
Код:
'...

Set objModiDoc = CreateObject("MODI.Document")
Call objModiDoc.Create(sFile)
Call objModiDoc.OCR(9, bAutoRotate, bAutoStraighten)

Set objModiImage = objModiDoc.Images(0)
sText = objModiImage.Layout.Text

' ...

Call objModiDoc.Close(False)
Агент нормально проходит 100-150 документов, а потом... Lotus падает.

Вот фрагмент NSD'шки:
Код:
############################################################
### FATAL THREAD 15/20 [ NLNOTES: 05d4: 0484]
### FP=0x0706e1cc, PC=0x07196924, SP=0x0706ddd0
### stkbase=07070000, total stksize=262144, used stksize=8752
### EAX=0x09936fd8, EBX=0x00000002, ECX=0x0706e1e8, EDX=0xd3ff0000
### ESI=0x09924008, EDI=0x09937000, CS=0x0000001b, SS=0x00000023
### DS=0x00000023, ES=0x00000023, FS=0x0000003b, GS=0x00000000 Flags=0x00010246
Exception code: c0000005 (ACCESS_VIOLATION)
############################################################
[ 1] 0x07196924 MSPCORE.IsFileOfSupportedType@8+234454 (9924008,706e1e8)
[ 2] 0x46c2fdb6 XPAGE3C (706e314,706e258)
[ 3] 0x46f12d38 XOCR3 (7834c58,706e314)
[ 4] 0x46c331f0 XPAGE3C (706e430,1)
[ 5] 0x46c56b6e XPAGE3C.XP_ParseXDoc+126 (96,706e430)
[ 6] 0x0719a663 MSPCORE.IsFileOfSupportedType@8+250133 (ffffffff,90f0020)
[ 7] 0x0719a84f MSPCORE.IsFileOfSupportedType@8+250625 (90f0020,b6f63676)
[ 8] 0x0719adbf MSPCORE.IsFileOfSupportedType@8+252017 (9924010,9a84508)
[ 9] 0x071972c5 MSPCORE.IsFileOfSupportedType@8+236919 (9924010,9a84508)
[10] 0x070c16f6 MDIVWCTL.DllUnregisterServer+171571 (9a84508,0)
[11] 0x070bf6e4 MDIVWCTL.DllUnregisterServer+163361 (9a84508,9)
[12] 0x77125d81 OLEAUT32.DispCallFunc+195 (78d9de0,3c)
[13] 0x77126390 OLEAUT32.DispCallFunc+1746 (19a234,78d9de0)
[14] 0x07083620 MDIVWCTL (78d9de0,a)
@[15] 0x00f585d9 nnotes.LSsThread::OleInvokeI+281 (2,78d9de0)
@[16] 0x00f58865 nnotes.LSsThread::OleInvoke+181 (6911908,1)
@[17] 0x00531dd3 nnotes.LSsThread::NRun+5811 (6911528,0)
@[18] 0x005324d6 nnotes.LSsThread::Run+182 (6911528,706ecb0)
@[19] 0x005b637d nnotes.LSsInstance::Resume+29 (66eb330,6c93614)
@[20] 0x00f40946 nnotes.LSIThread::Run+86 (6c93614,0)
@[21] 0x00f405f8 nnotes.LSIThread::RunInternal+72 (7060002,0)
@[22] 0x00f4086c nnotes.LSIThread::RunToCompletion+332 (6c93614,0)
@[23] 0x00f3c69f nnotes.CLSIDocument::RunScript+639 (6c93594,d5)
@[24] 0x00ac365a nnotes.CRawActionLotusScript::Run+554 (29ff,6811d14)
@[25] 0x00abfbfa nnotes.CRawAction::Run+58 (0,6811c14)
@[26] 0x00ac07ad nnotes.CRawAction::Execute+221 (24c0e94,2a0b)
@[27] 0x00ab8c36 nnotes.CAssistant::RunAlone+22 (681f014,6811c14)
@[28] 0x00abdbdb nnotes.CAssistant::Run+3595 (681f014,706fee4)
@[29] 0x61aad6c2 nnotesws.RunAssistantEx@28+482 (0,6811aa0,0,1,0,0,0)
@[30] 0x61fe4b84 nnotesws.CThreadAssistTwi::WorkItem+308 (3,6811a14,0,412,0,0,0)
@[31] 0x618109c8 nnotesws.CTwi::TwiThread+392 (0,706ffb4,613160,6811a14,0,0,0)
@[32] 0x6180ea0e nnotesws.TwiThreadProc+14 (6811a14,0,0,0,0,0,0)
@[33] 0x00613160 nnotes.ThreadWrapper@4+208 (0)
[34] 0x7c80b699 kernel32.GetModuleFileNameA+442 (613090)
В целом я не склонен винить MODI как таковой.
Подобную картину я наблюдал в агенте, работавшем на сервере и использовавшем объекты Windows Scripting для работы с файлами и папками.
Целый день работал нормально - потом сервер падал.
Пришлось переписать все с использованием родных LS-функций, после чего агент перестал валить сервер.

Бывало у кого-нибудь такое?..

Заранее спасибо за ответы!
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
271
#2
возможно "неправильное" овобождение памяти (попросту - утечка и наложение областей)...
посмотрите - может убивать (хотя не знаю - как) объект типа: Delete objModiDoc
но мысли правильные - использование внутри Нотуса таких конструкций (вызовы КОМ в том числе) усточивость не повышают :D
пргобуйте рулить "наоборот"...
выложить все нужные доки в каталог - натравить на них прогу (шелом, в пакетном режиме)

вот эта штука [14] 0x07083620 MDIVWCTL (78d9de0,a)
мне кажется вызывает "визуализацию" она тоже может быть причиной (нотуса не любят перехвата "окон")
 
D

D!m@n

#3
Спасибо, что отозвались!

Код:
Call objModiDoc.Close(False)
- закрыть Microsoft Office Document Imaging. Соответственно, здесь и память должна освобождаться.
Но я здесь ничего поделать не могу, т.к. за это сам компонент отвечает.
Потом я еще делаю вот так:
Код:
Set objModiDoc = Nothing
Но, по-моему, от этого Лотусу ни холодно, ни жарко.
А mdivwctl.dll - этот как раз и есть библиотечка компонента MODI.

Насчет визуализации - х его з... Свойств типа "Visible", "ScreenUpdating" у MODI.Document (в отличие от, например, Excel.Application) нет, поэтому тут все равно ничего не поделаешь... Окна на экране не мелькают, и на том спасибо :)

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

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
271
#4
боюс - не срастется с КОМ (я в это мало верю)...
может есть человеческое АПИ к этому пакету? Замапить его в прямые вызовы ДЛЛ из Нотусов (в LS) и делов-то
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#6
а проблема точно не в файлах-картинках, которые подсовываешь для обработки?..
из какого-нить басика те же объемы данных можешь попробовать обработать, каков результат?..

как вариант, попробуй написать библиотеку-врапер для объекта, т.е. сделать пару функций - обрабтка файла, папки...
и из лотуса вызывать уже функции из библиотеки... хз, но може поможе :)
 
D

D!m@n

#7
из какого-нить басика те же объемы данных можешь попробовать обработать, каков результат?..
Здравая мысль!
Написал прогу на C#, которая делает примерно то же самое.

Код:
			OpenFileDialog dlg = new OpenFileDialog();
dlg.DefaultExt = "tif";
dlg.Filter = "TIFF|*.tif*";
if (dlg.ShowDialog() == DialogResult.OK)
{
string sRecognized = "";
for (int i = 0; i < 1000; i++)
{
MODI.DocumentClass doc = new MODI.DocumentClass();

doc.Create(dlg.FileName);

doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true); // OutOfMemoryException на 127-м проходе

MODI.Image modiImg = (MODI.Image)doc.Images[0];
MODI.Layout layout = modiImg.Layout;

doc.Close(false);

sRecognized = layout.Text;

}
MessageBox.Show(sRecognized);
}
Результат - OutOfMemoryException на 127-м проходе в строке, вызывающей метод OCR().

Тогда модифицировал код вот так:
Код:
			OpenFileDialog dlg = new OpenFileDialog();
dlg.DefaultExt = "tif";
dlg.Filter = "TIFF|*.tif*";
if (dlg.ShowDialog() == DialogResult.OK)
{
string sRecognized = "";
for (int i = 0; i < 1000; i++)
{
MODI.DocumentClass doc = new MODI.DocumentClass();

doc.Create(dlg.FileName);

doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);

MODI.Image modiImg = (MODI.Image)doc.Images[0];
MODI.Layout layout = modiImg.Layout;

doc.Close(false);

sRecognized = layout.Text;

// добавил 4 строки ниже
Marshal.FinalReleaseComObject(doc);
Marshal.FinalReleaseComObject(modiImg);
Marshal.FinalReleaseComObject(layout);

GC.Collect();

}
MessageBox.Show(sRecognized);
}
Результат - AccessViolationException ("Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена."), и всего-то на 64-м проходе (в той же строке).

Так что вывод таков - либо я не умею работать с COM ни в Лотусе, ни на .NET'е (но прежде чем согласиться с этим вариантом, укажите мне на мои ошибки :)), либо сам компонент кривой.

Жаль, конечно, что Лотус некорректно обрабатывает эту ситуацию и падает... Генерил бы тоже исключение или хотя бы просто прибивал агента...
 

abbatik

Lotus team
20.10.2008
277
0
#8
А что вам мешает самому обработчик ошибки написать?

Или попробуйте пересоздавать объект, скажем раз в 50 проходов...
 
D

D!m@n

#9
А что вам мешает самому обработчик ошибки написать?
На C#? Ничего :) Только мне-то хотелось бы агента на LS, а не прогу на C#...

Или попробуйте пересоздавать объект, скажем раз в 50 проходов...
А его итак нужно каждый раз пересоздавать, т.к. после вызова метода Close() использовать объект MODI.Document невозможно.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
271
#10
написать OnError в Нотусе - у вас его там не наблюдается...
насколько кривой компонент - не знаю, жалобы в тырнете на него видел
 
D

D!m@n

#11
написать OnError в Нотусе - у вас его там не наблюдается...
Товарищи, ну Вы что, надо мной смеетесь, что ли? :)
Я ж говорю - Лотус ПАДАЕТ. А не ошибку генерит. Вон же NSD-шка в первом посте выложена.
Так что On Error не поможет.
Обработчик ошибок у меня в агенте, кстати, есть, просто я его здесь не стал писать для краткости.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#12
Товарищи, ну Вы что, надо мной смеетесь, что ли?
думаю, да, причем в извращенной форме! ))

конечно не удобное решение, но если попробовать сделать библиотеку-враппер для компонента? там же в ней обрабатывать исключения...
либо ищи Java-библиотеку нужную!
lmike не сталкивался с таким еще, видать, бо уже давно бы предложил замену, наверное :)
 
D

D!m@n

#13
Насчет библиотеки-обертки - в принципе, хорошая идея.
Но вот за что я люблю Лотус: написал агента - и 100 человек через 5 минут им могут пользоваться.
А при использовании "враппера" такой красоты уже не будет. Каждому - установи...
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
271
#15
Akupaka
толковые OCR - платные, а от мелкососа - бесплатная (но судя по всему - кривая)

D!m@n
мда... обшибся - сори
Наскока понял - у энтого КОМа наступает кома :) по памяти (вот писатели блин) и он честно валит Нотус ;)
хорошие тулзы у МС :)
выхода два - ждать патча, искать замену...
во втором случае - придется ставить софт (полюбому)
 
D

D!m@n

#16
фигня, делаешь документ, вкладываешь библиотеку, агент библиотеку распаковывает, а потом запускает нужный агент
А что? Хороший вариант!

толковые OCR - платные, а от мелкососа - бесплатная (но судя по всему - кривая)
Чесслово, по качеству распознавания текста - MODI работает вполне прилично.
Во всяком случае, для бесплатной примочки к офису.