Внедрение в базу и дальнейшее использование файла

  • Автор темы SparkLone
  • Дата начала
S

SparkLone

#1
Доброго, уважаемые.
Необходимо сделать базу данных, которая при старте запустит Exe файл. Т.е. база по сути инсталляционная, ее будет стартовать админ и для выбранных пользователей с помощью извлеченного EXE файла будут проведены определенные действияю не подскажете как это сделать?
Честно просмотрел все 60 листов форума, но по моему все не то..
Зачастую обсуждается как извлечь файлы пришедшие в письме или прикрепить программно и отправить письмом, а вот как работать с прикрепленными файлами ручками (в дизайнере), чтобы потом иметь к ним программный доступ не понятно..
По большей части все советы касаются работы с Rich Edit полем, может я чего то не понимаю, но в него не вставить файл в дизайнере.

Что пробовал: просто создал новую базу, добавлял аттач (в меню create -> attachment -> нужный файл). Файл отображается на форме. Дебаггер показывает, что HasEmbedded для документа false.

В общем проблемы как минимум 2:
1) как все таки прикрепить файл в дизайнере и как потом программно к нему достучаться
2) надо как то спрятать прикрепленный файл, чтобы он не показывался на форме при открытии в Lotus Notus.

Спасибо.
 

Omh

Lotus team
04.07.2007
2 210
1
#2
Если хочешь на этапе дезигнинга, то делаешь какую-либо форму (на QO можно поставить Continue = False).
Потом в своей чудо-кнопке берёшь её через NotesNoteCollection и детачишь файл.

Либо делаешь форму с ричтекстом "Install", перед посылкой тома админу создаешь документ, атачишт файл и в своей чудо-кнопке обращаешься к документу и детачишь файл.
 

DNT

Постоялец форума
Lotus team
12.10.2005
594
2
#3
1.
...
Dim doc As notesdocument
Dim rtitem As NotesRichTextItem
Dim object As NotesEmbeddedObject

...

Set rtitem = New NotesRichTextItem (Doc,"Body")
Set object = rtitem.EmbedObject (EMBED_ATTACHMENT, "", PathFile$)
Call Doc.Save(True,True)

....
'Body - имя RT поля
'PathFile$ - путь к файлу

2.
Поле "Body" просто скрываете через свойства поля - Hide paragraph from Lotus

P.S. на форуме уже есть точно всё это
 

Omh

Lotus team
04.07.2007
2 210
1
#4
Для: DNT
Ну richtext просто так не скрыть.
Либо в секцию, либо в программатик тэйбл.
 
F

fvoice

#6
Для: SparkLone
без дизайнера, но тоже вариант:
Сделайте форму с одним RichText полем, откройте ее, добавьте файл, сохраните, в дизайнере поставьте в свойствах формы auto launch - first attachmet.

При открытии этого документа будет запускаться приложение из поля, а форма не будет даже открываться.
Можно попробовать сделать этот документ профильным, и открывать его будет гораздо проще, даже UNIDа знать не надо.
 
S

SparkLone

#7
Для: Omh
Спасибо, пробую вариант с NotesNoteCollection, опыта в Лотусе маловато, так что медленно пробую )

Для: DNT
1. Не совсем понял. Вы динамически создаете RT поле "Body", и прикрепляете к нему файл из файловой системе. После закрытия базы файл останется в ней в виде embeded'а?
Т.е. после отработки этого кода его нужно будет убрать, и написать код который использует embeded файл, так?

2. Согласен с Omh, RT - поле вообще гемор редкостный, в свое время секциями пришлось оборачивать. Столько времени на подгонку дизайна ушло..

Для: fvoice
Думал об этом, но не вариант. В этом случае Exe запустится 1 раз и при старте. А мне надо запустить его с нужными параметрами после того как админ отметит чекбоксами нужных юзеров.
 
F

fvoice

#8
Для: SparkLone
Админ запустит его на машинах пользователей? Это как?
 
S

SparkLone

#9
Для: fvoice
Я не писал, что админ будет запускать базу на машинах пользователей.
Было сказано "ее будет стартовать админ и для выбранных пользователей с помощью извлеченного EXE файла будут проведены определенные действия". Если конкретней, - exe пропатчит мейловые базы нужных пользователей (при серверном типе установки Lotus'а у пользователя конечно)
 

Omh

Lotus team
04.07.2007
2 210
1
#10
Для: SparkLone
Ну то что richtext редкостный гемор, я особо не согласен :)

Давай решим вот что: ты хочешь внедрить файл именно на этапе дизайна?
Или потом, в уже задизайненной базе сделать документ с richtext'ом и в него приложить файл?

Говори как надо, а мы скажем, что для этого надо сделать :)
 
S

SparkLone

#11
Для: Omh
Ну не знаю, видимо сломался у меня на Лотусе драйвер straight_hands.sys )
В данный момент интересует именно вариант внедрить файл на этапе дизайна. В идеале - человек открывает базу, ему выводится список юзеров, он отмечает этих юзеров (вложенный файл нигде не видно), нажимает кнопку, и тут extract'ится файл и выполняет то что надо :)

-----
Решил поковырять способ предложенный уважаемым DNT. Сделал две кнопки:
1) Insert File
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim object As NotesEmbeddedObject
Set db = session.CurrentDatabase
Set doc = CurDocument.Document
Set rtitem = New NotesRichTextItem( doc, "Body" )
Set object = rtitem.EmbedObject ( EMBED_ATTACHMENT, "", "c:\setup.exe")
Call doc.Save( True, True )
End Sub

2) Run
Sub Click(Source As Button)
Dim doc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim fileCount As Integer
Const MAX = 100000
fileCount = 0
Set doc = CurDocument.Document

Set rtitem = doc.GetFirstItem( "Body" )
If ( rtitem.Type = RICHTEXT ) Then
Messagebox "d"
Forall o In rtitem.EmbeddedObjects
If ( o.Type = EMBED_ATTACHMENT ) _
And ( o.FileSize > MAX ) Then
fileCount = fileCount + 1
Call o.ExtractFile _
( "d:\reports\newfile" & Cstr(fileCount) )
Call o.Remove
Call doc.Save( True, True )
End If
End Forall
End If
End Sub

Если нажимать сначала Insert, потом Run - все работает. Если к примеру нажать Insert. Закрыть базу, открыть и нажать run - уже не рабоатет.. (не сохраняется состояние?)
+ ко всему размер базы растет каждый раз даже после нажатия Run, который по идее должен удалять файл (сохраняется но криво? :) )

В общем был бы благодарен за помощь )
 

Omh

Lotus team
04.07.2007
2 210
1
#12
Для: SparkLone
Если на этапе дизайна то делаем так:
Допустим твой файл зовётся prg.exe

В дизайнере делаем новую форму, назовём её допустим Prg
В дизайнере прикладываем на форму файл, на всякий случай на ивенты QueryOpen и QuerySave ставим Continue = False (что бы юзера случайно не наплодили документов с тяжёлой формой).
Всё, файл в дизайне мы создали.

Теперь идём к кнопке.
Пишу на память, так что сразу может и не откомпилиться :)
Код:
Dim Sess As New NotesSession
Dim Db As NotesDatabase
Set Db = sess.CurrentDatabase

Dim NNc As NotesNoteCollection
Set NNc = Sess.CreateNoteCollection(False)
NNc.SelectForm = True
NNc.SelectionFormula = {@Implode($Title; "") = "Prg"} '$Title - мультивэлью, точнее двухвэлью...

Call NNc.BuildCollection
Если всё правильно, то в данный момент у тебя в NNc содержиться NoteID документа формы (форма тот же документ).
Там есть пара методов перебора NNc, это посмотри сам.

В итоге у тебя в стринговой переменной есть NoteID документа формы.
Берёшь по этому NoteID документ из базы и из поля $Body экстрактишь приложенный тобой файл.
Запускаешь с параметрами и усё.

Я предложили такой извращённый способ, потому что когда-то проверял и вроде работало :)
Потому как если это файл приложить в SharedResources -> Files, то потом до него кроме как через DXL хрен доберёшься.
 

Omh

Lotus team
04.07.2007
2 210
1
#13
Хотя я бы сам делал бы форму "install" с рич тестом и уже в задизайненной базе делал бы такие инсталляции, как мне надо.
Но вышеуказанный способ тоже имеет право на жизнь, особенно, если не хочеться делиться самим exe файлом.
Правда, любой маломальски продвинутый пользователь/программер это дело вскроет со временем (хотя бы из за детачинга...).
 
S

SparkLone

#14
Omh
Огромное спасибо, за знания и терпение ) Немного вкурил в тему. Вот что вышло в итоге (экстрактим аттач, сохраняем на винт, запускаем, ждем пока отрабатывает, удаляем из базы аттач):
Код:
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim handle As Variant
Dim pathToFile As String
Dim NNc As NotesNoteCollection

Set db = session.CurrentDatabase
Set FSO = CreateObject("Scripting.FileSystemObject")
Set NNc = db.CreateNoteCollection(False)
NNc.SelectForms = True
NNc.SelectionFormula = {@Implode($Title; "") = "container"}
Call NNc.BuildCollection

nid = NNc.GetFirstNoteId
Set doc = db.GetDocumentByID(nid)
Set rtitem = doc.GetFirstItem("$Body")
Forall o In rtitem.EmbeddedObjects
%REM
Set handle = o.Activate( False )
%ENDREM
Set WshShell = CreateObject("WScript.Shell") 
pathToFile = WshShell.ExpandEnvironmentStrings("%temp%")	 & "\" & o.source
o.ExtractFile(pathToFile)
ReturnCode = WshShell.Run(pathToFile, 1, True)
Msgbox "OK"
o.Remove
Call doc.Save(True, True)
FSO.DeleteFile pathToFile
End Forall
End Sub
Ну а теперь вопросы, как же без них? :)
1) Set handle = o.Activate( False )
Это и не должно работать для обычных EXE файлов, я правильно понимаю? Только для документов которые зарегистрированы в системе и у которых можно дернуть интерфейс? (если есть способ запустить exe прям в качестве аттача - хотелось бы его узнать, от многих проблем избавляет, ибо не надо сохранять на винт и т.д.)
2) Set WShell = CreateObject("WScript.Shell")
Соответственно единственный вариант чтобы запустить вложение - сохранить и запустить файл благодаря WScript.Shell, да?
Не в курсе, есть ли подводные камни, на разных осях? База будет разворачиваться под W2k/XP/Vista. С той же Вистой я уже хлебнул горя, благодаря ее UAC'у - pain in ass у программиста..
3) WshShell.ExpandEnvironmentStrings("%temp%")
Опять таки есть ли другие способы получить путь в Temp директорию, окромя WScript'а? Сохранять буду только туда, ибо под той же Вистой вечно ни на какие папки прав нет, даже у админа, пока явным образом права UAC'ом не повысишь..
4) o.Remove
Работает/не работает? С одной стороны отрабатывает без ошибок. С другой стороны размер базы не уменьшается. Более того, провел эксперимент:
- создал базу
- в ней создал форму
- на форму зааттачил файл в дизайнере
- сохранил (Посмотрел размер)
- удалил в дизайнере файл
- сохранил
В итоге размер как был, так и остался большим, хотя в дизайнере файла не наблюдается.
Можно ли как то удалять attach'менты наверняка? А то увеличивать базы на 10 метров навсегда - дурной тон...
5) Set FSO = CreateObject("Scripting.FileSystemObject")
FSO.DeleteFile pathToFile
По моему это самый простой и надежный способ удаления файла, но опять таки завязка на систему (вдруг скриптинга не будет или версия кривая). Есть другие стабильные варианты? А то просматривал функцию удаления файла Елены Нефедовой и фигел, мрачно.. ) http://codeby.net/forum/threads/8273.html

И еще раз спасибо за помощь :)
 

Omh

Lotus team
04.07.2007
2 210
1
#15
1. Только для Embedded чё-то там, для аттачментов действительно не воркает.
2. Можно с помощью CreateProcessA и WaitForSingleObject (в нете найти легко)
3. Ф-ия скрипта Environ
4. Надо компактить базу после удалаения аттачей
5. Ф-ия скрипта Kill

А зачем ты удаляешь аттачмент из формы?
Он тебе больше никогда не понадобиться.
Да и там права надо что-то около Дизайнера и выше для этого, кмк.
 
S

SparkLone

#16
1. Жаль конечно..
2. Угу, читал в двух темах
http://codeby.net/forum/threads/19384.html?hl=CreateProcessA (сошлись на мнении что надо использовать WScript и нечего извращаться)
http://codeby.net/forum/threads/14257.html?hl=CreateProcessA
В общем если WScript будет работать на всех системах - остановлюсь на нем, если нет - буду разбираться с использованием WinAPI в Лотусе.
3, 4, 5: Cенкс, не знал )

На самом деле будут две разных базы. Одна админская - в ней удалять ничего не надо. А для юзеров (после применения как раз сохраненного приложения в админской базе) вроде как надо, я еще обсужу требования, может есть резон оставлять. Опять таки еще не ясно, что лучше - отправить юзерам письмо с инсталлятором, или проинтегрировать в их базы, чтобы при первом открытии - запустилась msi'ка (а потом соответственно удалился, место жалко, тем более что инсталлятор будет просечен многим юзером и дисковое пространство будет серверное).

Так что вопрос: получится ли засетить жестко msi в базы пользователей? В отличи от решенно благодаря тебе проблемы - в этом случае будет изменен шаблон мейловой базы юзеров, он накатится на текущие базы юзеров (проапдейтим дизайн). Т.е. если в темплейте просетить msi интеерсно он накатится на текущие nsf'ы или нет.
И какие есть вообще вараинты апдейта дизайна (замечу что помимо msi, там действительно будет меняться дизайн)?
Я знаю 2:
1) nconvert - официальная утилитка. В минусах у нее то, что после применения отправляет сама каждый раз письмо пользователям что их база была проапдейчена - что абсолютно лишнее :)
2) с помощью lncppapi. В минусах то - что надо выносить отдельный exe, хотя терпимо. В принципе на этом методе и остановлюсь если вариантов лучше нет.
 

Omh

Lotus team
04.07.2007
2 210
1
#17
Вторую часть вопроса до упора не понял, но если накатить дизайн с файлом в форме, то, кмк, файл появиться и в дизайне target базы.
 
30.05.2006
1 345
11
#18
Глупый вопрос: почтовые базы, которые надо апгрейдить, они НЕлотусовые? Може на них просто стандартную задачу DESIGN натравить?