• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Программно Изменить Время Запуска Шедульного Агента

  • Автор темы AGat
  • Дата начала
A

AGat

Всем привет,

Возник сабжевый вопрос. Наваял второй агент для экспорта первого агента в dxl, изменения времени и импорта обратно:

Код:
Sub Initialize
On Error GoTo Except

Dim nc As NotesNoteCollection
Dim noteID As String
Dim aDoc As NotesDocument
Dim profileDoc As NotesDocument
Dim rtItem As NotesRichTextItem
Dim dxE As NotesDXLExporter
Dim xml As String
Dim posStart As Long
Dim dxI As NotesDXLImporter

'get agent document
Set nc = CommonTools_Db.CreateNoteCollection(False) 'CommonTools_Db - текущая БД
nc.SelectAgents = True
nc.BuildCollection
noteID = nc.GetFirstNoteId
Do While noteID <> ""
Set aDoc = CommonTools_Db.GetDocumentById(noteID)
If aDoc.GetItemValue("$TITLE")(0) = "яя" Then Exit Do
noteID = nc.GetNextNoteId(noteID)
Loop

'prepare rt item
Set profileDoc = CommonTools_Db.GetProfileDocument("tmp", "")
While profileDoc.HasItem("Tmp")
profileDoc.RemoveItem "Tmp"
Wend
Set rtItem = profileDoc.CreateRichTextItem("Tmp")

'export dxl to rt item
Set dxE = CommonTools_Session.CreateDxlExporter(aDoc, rtItem) 'CommonTools_Session - объект NotesSession
dxE.ForceNoteFormat = False
dxE.Process
Delete dxE

'change launch time
xml = rtItem.GetUnformattedText
posStart = InStr(xml, "<starttime><datetime>") + 21
Mid$(xml, posStart, 10) = "T232300,00" 'выставим время запуска агента в 23:23 (проверял, замена текста работает корректно)

'import agent
Set dxI = CommonTools_Session.CreateDxlImporter
dxI.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE
'здесь пытался вставлять различные опции импорта, не помогает.
dxI.Import xml, CommonTools_Db

'sign imported agent
noteID = dxI.GetFirstImportedNoteId
Delete dxI
Set aDoc = CommonTools_Db.GetDocumentById(noteID)
aDoc.Sign
aDoc.Save True, False

GoTo Finally

Except:
CommonTools_CommonErrorHandler LibName + "Initialze", Err, Erl, Error$, Nothing
Resume Finally
Finally:
End Sub

Вечером протестировал, работает, время запуска агента заменяется. Утром на всякий случай проверяю этот же код - не работает. Куда можно копнуть, или плюнуть уже на эту кривизну и лезть в api?
 

lmike

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

Добавлено: и еще - может в сторону задач посмотреть
 
A

AGat

а если повторно выгрузить - дата нормально выглядит?
т.е. сравнить исходный (выгруженный) и новый
и второй момент - может amgr дурит (это часто бывает)

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

Самая мякотка: если делать выгрузку и загрузку двумя отдельными агентами, то оно вообще не работает.
Код экспорта:
Код:
Sub Initialize
On Error GoTo Except

Dim nc As NotesNoteCollection
Dim noteID As String
Dim aDoc As NotesDocument
Dim profileDoc As NotesDocument
Dim rtItem As NotesRichTextItem
Dim dxE As NotesDXLExporter

'get agent document
Set nc = CommonTools_Db.CreateNoteCollection(False)
nc.SelectAgents = True
nc.BuildCollection
noteID = nc.GetFirstNoteId
Do While noteID <> ""
Set aDoc = CommonTools_Db.GetDocumentById(noteID)
If aDoc.GetItemValue("$TITLE")(0) = "яя" Then Exit Do
noteID = nc.GetNextNoteId(noteID)
Loop

'prepare rt item
Set profileDoc = CommonTools_Db.GetProfileDocument("tmp", "")
While profileDoc.HasItem("Tmp")
profileDoc.RemoveItem "Tmp"
Wend
Set rtItem = profileDoc.CreateRichTextItem("Tmp")

'export dxl to rt item
Set dxE = CommonTools_Session.CreateDxlExporter(aDoc, rtItem)
dxE.ForceNoteFormat = False
dxE.Process
Delete dxE

'save agent xml
Open "d:\agent.xml" For Output As #1
Print #1, rtItem.GetUnformattedText
Close #1

GoTo Finally

Except:
CommonTools_CommonErrorHandler LibName + "Initialze", Err, Erl, Error$, Nothing
Resume Finally
Finally:
End Sub

Экспортируем, всё ок, файлик можно посмотреть. Ничего с файликом не делаем, пытаемся импортировать обратно:

Код:
Sub Initialize
On Error GoTo Except

Dim noteID As String
Dim aDoc As NotesDocument
Dim dxI As NotesDXLImporter
Dim stream As NotesStream

Set stream = CommonTools_Session.Createstream
stream.Open "D:\agent_new.xml"

'import agent
Set dxI = CommonTools_Session.CreateDxlImporter(stream, CommonTools_Db)
dxI.AclImportOption = DXLIMPORTOPTION_IGNORE
dxI.DocumentImportOption = DXLIMPORTOPTION_IGNORE
dxI.ReplaceDbProperties = False
dxI.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE
dxI.CompileLotusScript = True
dxI.ReplicaRequiredForReplaceOrUpdate = False
dxI.Process

'sign agent
noteID = dxI.GetFirstImportedNoteId
Delete dxI
Set aDoc = CommonTools_Db.GetDocumentById(noteID)
aDoc.Sign
aDoc.Save True, False

GoTo Finally

Except:
CommonTools_CommonErrorHandler LibName + "Initialze", Err, Erl, Error$, Nothing
Resume Finally
Finally:
End Sub
Не импортируется, вываливает "DXL importer operation failed".

У кого-нибудь это вообще работает? Клиент 8.5.3 FP3, если что.
 
A

AGat

Разобрался вроде как, проблема в съехавшей кодировке и валидации xml. С кодировкой понятно, с валидацией решается добавлением dxI.InputValidationOption = VALIDATE_NEVER при импорте или вот так:
Код:
	'transform xml
xml = rtItem.GetUnformattedText
sysPath = CommonTools_Session.GetEnvironmentString("NotesProgram", True)
If Right$(sysPath, 1) <> "\" Then sysPath = sysPath + "\"
xml = CommonTools_StrReplace(xml, {'xmlschemas/domino_}, {'} + sysPath + {xmlschemas\domino_})
 

Leoric

Lotus Team
15.10.2003
68
9
BIT
23
Кодировка у вас ломается скорее всего из-за странного способа экспорта... или я не понял, зачем в нем RT и .GetUnformattedText.

Почему не используете стрим для экспорта?
Код:
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase

REM Open xml file named after current database
Dim stream As NotesStream
Set stream = session.CreateStream
filename$ = "c:\dxl\" & Left(db.FileName, Len(db.FileName) - 3) & "dxl"
If Not stream.Open(filename$) Then
Messagebox "Cannot open " & filename$,, "Error"
Exit Sub
End If
Call stream.Truncate

REM Export current database as DXL
Dim exporter As NotesDXLExporter
Set exporter = session.CreateDXLExporter
Call exporter.SetInput(db)
Call exporter.SetOutput(stream)
Call exporter.Process
End Sub
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
согласен с Leoric и еще - замену можно делать через XSLT (если объем небольшой) или SAX (если агент-нота большая)
 
A

AGat

Кодировка у вас ломается скорее всего из-за странного способа экспорта... или я не понял, зачем в нем RT и .GetUnformattedText.

Почему не используете стрим для экспорта?
Экспорт в RT по двум причинам:
1. это всего лишь проверка концепции, что время запуска агента действительно можно изменить и agent manager эти изменения воспринимает. Детали пока непринципиальны.
2. промежуточные файлы ненужны, как максимум нужно на этапе отладки посмотреть полученный xml.

Еще вопрос: можно ли использовать такую схему:
1. Экспортируем агент в NotesDomParser
2. В объекте NotesDomParser трансформируем xml
3. Импортируем агент из NotesDomParser
без создания промежуточных файлов? Возможно ли такое вообще? Если подскажете как именно тоже неплохо :)

PS
Сорь за чайниковопросы, сам уже лет 10 пользую собственную обертку для msxml и пока хватало на все случаи жизни. Поэтому с лотусовыми xml-объектами знаком не очень хорошо.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
без создания промежуточных файлов? Возможно ли такое вообще? Если подскажете как именно тоже неплохо smile.gif
да, можно
примерчик где-то выкладывал (тема была несколько иная - в хтмл преобразовывать дхл)

Добавлено: вот оно https://codeby.net/threads/53561.html?vi...st&p=246340

Добавлено: ключевое Call xml.Serialize
и создавать файл необязательно (stream может быть без файла)
 
A

AGat

Устал бодаться с этим лотусовым хмл. Есть такой код:

Код:
'кладем в targetDomParser хмл агента
Set targetDxlExporter = CommonTools_Session.CreateDXLExporter(targetAgentDoc)
Set targetDomParser = CommonTools_Session.CreateDomParser(targetDxlExporter)
targetDxlExporter.Process

'... долго и нудно ковыряем targetDomParser

'импортируем наковырянное обратно в агент
Set dxI = CommonTools_Session.CreateDxlImporter(targetDomParser, mailFile)
dxI.Process

На последней строке вылетает с "The Process method can be applied only To the first XML processor In an XML pipeline, Not one In the middle Or at the End". Вместо последней строки можно написать "targetDomParser.Process" с тем же результатом. Я что-то не понимаю?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
process - это какбэ последняя операция
а piplining - ну почитайте хэлп и примеры в тырнете


Добавлено:
 
A

AGat

Так и не понял концепцию с обработчиком on event и serialize.

Сейчас мне нужно:
1. Экспортнуть агент в xml
2. Подменить в нем ноды code, взяв их из другого агента
3. Импортнуть полученный xml обратно в агент.

Всё последовательно: DXLExporter -> DOMParser, меняем ноды, DOMParser -> DXLImporter. Куда тут прикручивать on event и serialize и главное зачем?
 
A

AGat

Если можно поясните пожалуйста на конкретном примере:

Код:
Dim targetDomParser As NotesDOMParser

'... получаем агента в targetDomParser, подмениваем ноды...

Dim dxI as NotesDXLImporter

Set dxI = session.CreateDxlImporter(targetDomParser, mailFile)
dxI.InputValidationOption = VALIDATE_NEVER
dxI.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE
dxI.CompileLotusscript = True
dxI.Process

Видимо у меня запор мыслепровода, никак не вкурю зачем тут обрабатывать события. Где конкретно нужно воткнуть обработчик PostDOMParse и targetDomParser.Serialize?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
парсер - это опционально - если надо менять дерево DOM
тогда и нужно событие

Добавлено: по ссылке
Код:
Call exporter.SetInput ( doc )
Call exporter.SetOutput ( domParser )
Call domParser.SetOutput ( importer )
получили со входа док, обработали какие-то ноды, что бы их обработать - надо вызвать обработчик, он будет вызван когда экспортер затронет output, потому как там - парсер, по событию вызовется ф-ция (калбэк), кот. получает аргументы
в конце ф-ции - надо возвратить результат (ноды меняли) - вызываем serialize
на выход парсеру подключен импортер...
все это называется pipeline
и по ссылка вполне-себе описано
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
забыл... там же выше (по коду) и создание объектов для пайплайна:
Код:
Set exporter = session.CreateDXLExporter
Set domParser=session.CreateDOMParser
Set importer = session.CreateDXLImporter ( domParser, db )
importer.DocumentImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE
а ниже - подключения евента к парсеру
Код:
On Event PostDOMParse From domParser Call PlayWithDXLRoutine
и заключительный аккорд - запуск всей схемы Call exporter.process
а кто там после кого - определяет задание input и output
разумеется надо создать ф-цию обработки по нодам, кот в примере называется PlayWithDXLRoutine с параметром - объект парсера, через кот и происходит обработка, в конце ф-ции (как и предсказано :p ) - serialize для объекта
Event PostDOMParse как раз произодет как только парсер построит дерево в памяти и управление получит ф-ция, через калбэк
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
616
223
BIT
9
Не слишком ли сложный путь вы выбрали?

Почему не воспользоваться ODS_ASSISTSTRUCT и менять документ агента напрямую?

Код:
Type ODS_ASSISTSTRUCT

wVersion	As Integer

wTriggerType	As Integer

wSearchType	As Integer

wIntervalType	As Integer

wInterval  As Integer

dwTime1	 As Long

dwTime2	 As Long

StartTime	As TIMEDATE

EndTime	As TIMEDATE

dwFlags	As Long

dwSpare (15)  As Long

End Type
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
177
Domino-Designer
+1
Где-то я еще видел код на вызов диалого свойств агента, как в дизайнере...
 
A

AGat

в конце ф-ции - надо возвратить результат (ноды меняли) - вызываем serialize
на выход парсеру подключен импортер...
все это называется pipeline
и по ссылка вполне-себе описано
Спасибо, покурил еще раз пример, концепцию осознал, проникся.
Вопрос: а как сделать например через стрим, но без открытия промежуточного файла?

Добавлено:
Не слишком ли сложный путь вы выбрали?

Почему не воспользоваться ODS_ASSISTSTRUCT и менять документ агента напрямую?
Поначалу так и хотел, но api уже много раз пройденный этап, а с дхл плотно еще не работал. Во-вторых, оказалось что нужно скриптом менять еще и код агента, тут уже наверное проще через дхл. Ну и в-третьих надо ориентироваться на поддержку имеющимся личным составом, поэтому решение желательно в рамках LS.
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
616
223
BIT
9
Поначалу так и хотел, но api уже много раз пройденный этап, а с дхл плотно еще не работал. Во-вторых, оказалось что нужно скриптом менять еще и код агента, тут уже наверное проще через дхл. Ну и в-третьих надо ориентироваться на поддержку имеющимся личным составом, поэтому решение желательно в рамках LS.

Вы меня просто впечатали в стену.
Извините, а слабо написать агента, часть кода которого в настроечных документах БД, что б в дизайн не лазить?

У меня стойкое ощущение, что вы сами себя кошмарите.
 
A

AGat

Вы меня просто впечатали в стену.
Извините, а слабо написать агента, часть кода которого в настроечных документах БД, что б в дизайн не лазить?

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

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