• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Xlapp.quit() Не Срабатывает После Errh

Eugen

Green Team
22.03.2012
210
1
BIT
1
Всем здрасьте.

Есть некий агент, формирующий отчет в xls. В случае ошибки хочу глушить процесс. Делаю так:
Код:
Sub Initialize
On Error GoTo errH

Dim xlApp, xlWorkbook, xlSheet
Dim curDoc as NotesDocument

Set xlApp = CreateObject({Excel.Application})
xlApp.SheetsInNewWorkbook = 1
Call xlApp.Workbooks.Add({})
Set xlWorkbook = xlApp.Workbooks(1)
Set xlSheet = xlWorkbook.Worksheets(1)

'тут будет заполнение отчета
xlWorkbook.Sheets(1).Name = {ТТ №} & curDoc.fldLRPNumber(0)

endSub:	
Exit sub
errH:
Print {Error "} & Error$ & {" in line } & Erl
If IsObject(xlApp) Then
Call xlApp.Quit()
End If
Resume endSub
End Sub
В этом случае curDoc не определен, вывалится ошибка и процесс должен убиться, но этого почему то не происходит, а если делаю так, то все ок:
Код:
Sub Initialize
On Error GoTo errH

Set xlApp = CreateObject({Excel.Application})
xlApp.SheetsInNewWorkbook = 1
Call xlApp.Workbooks.Add({})
Set xlWorkbook = xlApp.Workbooks(1)
Set xlSheet = xlWorkbook.Worksheets(1)

Call xlApp.Quit()

endSub:	
Exit sub
errH:
Print {Error "} & Error$ & {" in line } & Erl
If IsObject(xlApp) Then
Call xlApp.Quit()
End If
Resume endSub
End Sub
Т.е. если делать Call xlApp.Quit() не в обработчике ошибок, то нужный процесс убивается без проблем. Причем вот что странно - у меня стоит 2007 офис и есть глюки, у коллеги стоит 2010-й и у него все ок, т.е. процесс убивается вне зависимости от того, где размещается Call xlApp.Quit().

ЗЫ: Где то в соседней теме встречал такую фишку:
Код:
Sub CloseMSobj(execName As String)
On Error GoTo ErrH
Dim objs As Variant
Dim strSQL As String
Dim strWMI As String
strWMI = "winmgmts:"
strSQL = "Select * From Win32_Process "
strSQL = strSQL & {where Name = '} & execName &{'}
Set objs = GetObject(strWMI).ExecQuery(strSQL)
If Not objs Is Nothing Then
ForAll obj In objs
obj.Terminate
End ForAll
End If
Quit:
Exit Sub
ErrH:
Resume Quit
End Sub
, но мне это не подходит, т.к. она глушит вообще все процессы эхеля.
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
159
У нас так, пока глюков не было.
На рабочей машине MS_2010, у большинства пользователей тоже.
На части серверов 2003-2007.
DisplayAlerts не дает предупреждений о "Сохранить", может кстати из-за него и не закрывается.
Код:
GoTo endh
handler:
If Not wapp Is Nothing Then
wapp.DisplayAlerts = False
Call wapp.Quit()
Set wapp = nothing
End If
Resume endh
endh:
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
159
Бредово звучит, но похоже косяк в версии. Про 2007 везде пишут, что пока не сохранишь закрыть не дает.
Обходят через
Код:
ThisWorkbook.Saved = True
затем Quit
Типа ставят флаг для Application.ActiveWorkbook.Saved = True что она сохранена.
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Бредово звучит, но похоже косяк в версии. Про 2007 везде пишут, что пока не сохранишь закрыть не дает.
Обходят через
Код:
ThisWorkbook.Saved = True
затем Quit
Типа ставят флаг для Application.ActiveWorkbook.Saved = True что она сохранена.
И снова не помогло. В дебагере наблюдается вот такая картина:
Снимок.PNG
Шаг "Set xlApp = Nothing" уже прошел, а переменная xlApp еще не очистилась. Из-за чего такое может быть?
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
159
Хм,первый раз такое встречаю...
и условие isObject прошел и команды сделал...
Может сделать двойной обработчик ошибок? может в Excel при закрытии что падает, а логов нет.
Можно попробовать обновить версию, либо SP какой поставить к офису. Пользователи на каком сидят?

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

Eugen

Green Team
22.03.2012
210
1
BIT
1

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
а потом сервиспак для винды...
готов поспорить - что будете биться с траблой долго и возможно - переписать без эхеля займет меньше времени ;)
а потом проапдейтят эхель - опять что-то сломается... и по новой
 

garrick

Lotus Team
26.10.2009
1 349
151
BIT
164
Мне кажется некорректно без спроса пользователя закрывать Excel. А вдруг он в нём какую-то работу делает, помимо вашего отчёта, уже много написал и не сохранил?
1. Получайте объект Excel через GetObject - если Excel уже запущен, вы его получите, если нет получите ошибку в обработчике которой выполните CreateObject. Это убережет вас от запуска множества копий Excel, а так же может реанимировать зависшие ранее (иногда они оживают ;)).
2. Если вы сделали как написано в п.1 теперь вы точно знаете можете ли вы закрыть Excel, т.к. открыли его сами или нет, т.к. пользователь что-то делал в нём до вас.
3. Если закрывать Excel не надо, но вы хотите "скрыть" результаты формирования вашего отчёта, закройте созданный вами Workbook.
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Мне кажется некорректно без спроса пользователя закрывать Excel. А вдруг он в нём какую-то работу делает, помимо вашего отчёта, уже много написал и не сохранил?
Там же вроде на каждый документ свой отдельный процесс. Поэтому я и хотел сделать через .Quit - он убивает только собственный процесс.
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
159
Eugen
Это-то да, но может решим еще проблему почему вылетает с ошибкой?
По идее же ее быть не должно.
 

garrick

Lotus Team
26.10.2009
1 349
151
BIT
164
Там же вроде на каждый документ свой отдельный процесс. Поэтому я и хотел сделать через .Quit - он убивает только собственный процесс.
Раньше были прецеденты - в каких-то версия весь Excel закрывался сразу, больше с тех пор так никогда не делаю. Как там сейчас с 2007-2010 не знаю, может что-то пофиксили. Но опять же как оно будет дальше, в следующих версиях, тоже неизвестно.
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
В общем ересь какая-то... оставил в таком виде:
Код:
xlWorkBook.Saved = True
Call xlApp.Quit()
Set xlApp = Nothing
Вроде работает, пользователи не жалуются. Самый "прикол" в том, что и у меня заработало, хотя сервис пак так и не поставил... Чертовщина какая-то. :angry2:
ЗЫ: Если не сложно, дайте ссыль, где почитать про MS Office API.
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
159


ссылки на Excel, но там переходы есть.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
я так понимаю - неделя потрачена на эксперименты :angry2:
лучше теперь потратить время на изучение и кучу времени сбережете...
я понимаю лет 10-ть назад - эти инструменты либо отсут. либо были в зачаточном состоянии, но сейчас-то...
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Про POI слышал много хороших вещей и в планах стоит изучение, но в большинстве старых баз используются OLE-объекты, так что их тоже было бы неплохо знать.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
сделайте адаптер или рапер (шаблон программирования) и легко замените вызов Вин объекта на ваш...
я таким образом, в рамках проекта, менял вывод в Excel, на вывод в CSV (разные шиты - разные файлы, т.к. вркбук был многошитовый)
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
1. почему в обработчике просто не написать xlApp.Quit() ?
2. почему не перебдеть возможные ошибки?
  • контролировать наличие документа
  • не писать так curDoc.fldLRPNumber(0). Лучше curDoc.GetItevNalue( "fldLRPNumber" )(0). Тогда если поля нет - вернется пустая строка. Контролировать передачу дат в эксель
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!