После защиты паролем через библиотеку, макрос перестал работать

Автор Konstanta, 7 февраля 2020, 10:54

0 Пользователи и 1 гость просматривают эту тему.

Kadet

Беда с этими паролями.
Если не ставить пароль в самой инсталяхе, то при первой загрузке всё работает нормально. Библиотека копируется и на обе её копии ставится пароль (и вне и вну). Однако, если закрыть базу и открыть её снова (второй и далее раз). Внешняя библиотека так и остаётся запаролированной, а вот внутренняя остаётся в свободном доступе. И как я её не пытаюсь запароллирова, хоть с проверкой пароля, хоть без - она остаётся свободна в доступе.

'Хоть так:
ThisDatabaseDocument.BasicLibraries.changeLibraryPassword("MyLibrary",Ps,Pass)
'Или так:
If ( NOT ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary")) Then ThisDatabaseDocument.BasicLibraries.changeLibraryPassword("MyLibrary",Ps,Pass)

Не получается закрыть. При этом никаких ошибок не даёт.

А если, запароллировать в самой инсталяхе, то при первом запуске - крах.

Kadet

Вычислил. Крах, при запароллированной библиотеке в исталяхе происходит при разблокировке библиотеки:
If ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary") Then ThisDatabaseDocument.BasicLibraries.verifyLibraryPassword("MyLibrary",Pass)

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

Какая-то недоработка в LO с этой защитой происходит.

Для понимания выкладываю весь макрос. Он запускается во время загружки файла БД.
'*************************************************************************
Sub ThisDBDoc(oEvent)
Dim Ps
Ps = ""
ThisDatabaseDocument = ThisComponent
ThisDatabaseDocument.DataSource.Settings.RespectDriverResultSetType = false

sDBname = ThisDatabaseDocument.DataSource.URL

sDBURL=ThisDatabaseDocument.URL

ON LOCAL ERROR GOTO Error0:
ThisDatabaseDocument.BasicLibraries.LoadLibrary("MyLibrary")
ThisDatabaseDocument.DialogLibraries.loadLibrary("MyLibrary")
Error0:
ON LOCAL ERROR GOTO 0
If GlobalScope.BasicLibraries.hasByName("MyLibrary") Then
ON LOCAL ERROR GOTO Error00:
GlobalScope.BasicLibraries.loadLibrary("MyLibrary")
GlobalScope.DialogLibraries.loadLibrary("MyLibrary")
Error00:
ON LOCAL ERROR GOTO 0
'Этот код не работает. Защита не устанавливается. Ошибок не выдаёт.
If ( NOT ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary")) Then ThisDatabaseDocument.BasicLibraries.changeLibraryPassword("MyLibrary",Ps,Pass)
Else
StartOsn(Pass)
'На этом этапе происходит КРАХ при попытке разблокировать защищённую библиотеку
If ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary") Then ThisDatabaseDocument.BasicLibraries.verifyLibraryPassword("MyLibrary",Pass)
AddOneLib("MyLibrary", "MyLibrary", ThisDatabaseDocument.BasicLibraries, GlobalScope.BasicLibraries, true)
AddOneLib("MyLibrary", "MyLibrary", ThisDatabaseDocument.DialogLibraries, GlobalScope.DialogLibraries, false)
GlobalScope.BasicLibraries.loadLibrary("MyLibrary")
GlobalScope.DialogLibraries.loadLibrary("MyLibrary")
'Тут всё работает, хотя код полностью аналогичный тому, что до IF.
If ( NOT ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary")) Then ThisDatabaseDocument.BasicLibraries.changeLibraryPassword("MyLibrary",Ps,Pass)
GlobalScope.BasicLibraries.changeLibraryPassword("MyLibrary",Ps,Pass)
UserName = "Manager1"
ThisDatabaseDocument.DataSource.User = "Manager1"
End If
LoginID(UserName)
OpenForm0

End Sub


(Вложение - вариант с защитой и крахом)

sokol92

Думаю, что правильная последовательность действий для разблокировки библиотеки следующая:

Sub UnlockLibrary(Byval oDoc, Byval libName, Byval pass)
 With oDoc.BasicLibraries
   If .isLibraryPasswordProtected(libName) Then
     If Not .isLibraryPasswordVerified(libName) Then
       .verifyLibraryPassword(libName, pass)
     End If  
   End If
 End With
End Sub
Владимир.

Kadet

Цитата: sokol92 от 22 августа 2020, 16:35Думаю, что правильная последовательность действий для разблокировки библиотеки документа следующая:
К сожаления, не помогло. Может это у меня с компом что-то не то?
Хотя, вроде бы на рабочем компе было тоже самое. Хотя окончательного варианта там ещё не было.

sokol92

Проверяем. Вложенный документ имеет библиотеку Mylib c паролем "1".

Sub TestLib
  UnlockLibrary ThisComponent, "Mylib", "1"
End Sub


Для разблокировки глобальной библиотеки в качестве первого параметра нужно указать  GlobalScope.
Владимир.

Kadet

Добавил во внутреннюю библиотеку макросы UnlockLibrary и TestLib.
TestLib повесил на событие "Открытие документа".
Крах. Проверяем.

bk

Цитата: Kadet от 22 августа 2020, 17:27Добавил во внутреннюю библиотеку макросы UnlockLibrary и TestLib.
TestLib повесил на событие "Открытие документа".
Крах. Проверяем.

Питоньяк говорит: сначала загружаем библиотеку, потом пользуемся её макросами. В одной из книг он показывает, что загрузка библиотеки производится вспомогательным макросом из библиотеки Standart. Я это сделал так:
В библиотеке Standard Вашего файла я разместил вспомогательный макрос, разблокирующий библиотеку при загрузке:
Sub CallLoadLib()
Dim oLibs
oLibs = BasicLibraries
If oLibs.hasByName("MyLibrary") Then
oLibs.LoadLibrary("MyLibrary")
 If oLibs.isLibraryPasswordProtected("MyLibrary") Then
  If NOT oLibs.isLibraryPasswordVerified("MyLibrary") Then
  oLibs.verifyLibraryPassword("MyLibrary", "111")
  End If
  If oLibs.isLibraryPasswordVerified("MyLibrary") Then
      ThisDBDoc 'это уже тот Ваш макрос
  End If
 End If
End If
End Sub
Библиотека разблокируется. Но при первой загрузке файла дальше меня Ваше приложение не пропускает из-за ошибки входа (и закрывает файл). А со второй загрузки файла вижу, что библиотека разблокирована и могу вносить там изменения. Если файл закрыть, то при открытии всё повторяется. И если по пунктам - какая задача сейчас стоит перед Вами?
Если я правильно понимаю справку, changeLibrary меняет пароль, но это уже для следующей загрузки актуально, а в текущей сессии после смены пароля метод isLibraryPasswordVerified возвращает True, т.е. библиотека остается разблокированной. Об этом я писал на 4-й странице этой темы, что дальше каким-то образом нужно закрыть библиотеку, но  я к сожалению не знаю как (и не уверен, что вышеуказанные методы вообще для этого). Однако библиотеку можно защитить от изменений, если во вспомогательном макросе добавить строку кода :setLibraryReadOnly(Имя библиотеки, True). Но имейте ввиду, что после этого Вы сами не сможете изменить её (т.е. этот метод должен располагаться в том макросе, к которому Вы имеете доступ за пределами защищенной библиотеки (например, я это реализовал опять же в библиотеке Standard)

Kadet

Цитата: bk от 22 августа 2020, 17:56Питоньяк говорит: сначала загружаем библиотеку, потом пользуемся её макросами.
Дело в том, что в макросе ThisDBDoc в самом начале (после установочных строк) идёт подключение внутренних библиотек (Ответ #91), и дополнительный макрос не должен быть нужен:

ThisDatabaseDocument.BasicLibraries.LoadLibrary("MyLibrary")
ThisDatabaseDocument.DialogLibraries.loadLibrary("MyLibrary")


Цитата: bk от 22 августа 2020, 17:56Но при первой загрузке файла дальше меня Ваше приложение не пропускает из-за ошибки входа (и закрывает файл).
Это и есть крах. Т.е. - вначале идёт загрузка базы. Открывается окно базы, но загрузка продолжается. Потом окно базы само-собой (по воле макроса) закрывается и должна открыться форма "ОСНОВНАЯ" (с коричневой половой доской на фоне). Это правильное открытие базы загруженной тут - (Ответ #86). Этот вариант без пароля и работать должен правильно (по крайней мере у меня это так).
А при пароле вываливается маленькое окно с сообщением, что "крах". Судя по всему именно это у вас и происходит, так же как и у меня.

Цитата: bk от 22 августа 2020, 17:56Однако библиотеку можно защитить от изменений, если во вспомогательном макросе добавить строку кода :setLibraryReadOnly
Не удобный вариант. При ReadOnly библиотеки всё таки открыты, а не хотелось бы. К тому же, не нужно большого ума, чтобы сварганить и запустить простейший макрос и разблокировать эту библиотеку (ведь именно от подобных "умников" и ставится парольная защита).

bk

Цитата: Kadet от 22 августа 2020, 18:20Это и есть крах. Т.е. - вначале идёт загрузка базы. Открывается окно базы, но загрузка продолжается. Потом окно базы само-собой (по воле макроса) закрывается и должна открыться форма "ОСНОВНАЯ" (с коричневой половой доской на фоне). Это правильное открытие базы загруженной тут - (Ответ #86). Этот вариант без пароля и работать должен правильно (по крайней мере у меня это так).
А при пароле вываливается маленькое окно с сообщением, что "крах". Судя по всему именно это у вас и происходит, так же как и у меня.

Поэтому я и ссылаюсь на Питоньяка: загрузку библиотеки попробуйте провести вспомогательным макросом из библиотеки Standard. Если конкретно в моем примере закомментить вызов Вашего макроса ThisDBDoc, то файл спокойно открывается без краха и с разблокированной библиотекой. Это означает, что крах вызывает не действия с библиотеками, а какая-то другая функция, например, проверки ошибки входа и пароля. Но так много макросов у Вас, нет столько времени их смотреть. К тому же и в макросе ThisDBDoc у Вас столько раз обработка ошибок в выходом в 0, что не понятно как искать ошибку.

Kadet

Ну, что можно сказать.
Поставил CallLoadLib во внутренний Standard и повесил его на открытие файла.
Сначала выдавал ошибку в CallLoadLib() при подключении библиотеки на - oLibs.LoadLibrary("MyLibrary"). Окружил LoadLibrary("MyLibrary") обходом ошибки. Вроде бы проскочил. Вроде бы распечатал библиотеку без краха. Даже создал библиотеку в глобале.
Но, вот не задача, библиотека создана, все модули присутствуют, но все они пусты. Ни одного макроса не перенеслось. При этом - все диалоги библиотеки скопировались нормально.

Параллельно попробовал переработать и свой макрос. Вынес строку:
f ThisDatabaseDocument.BasicLibraries.isLibraryPasswordProtected("MyLibrary") Then ThisDatabaseDocument.BasicLibraries.verifyLibraryPassword("MyLibrary",Pass)
из If и поставил её сразу после подключения библиотек.
Происходит то же, что и с допмакросом bk - библиотека якобы разблокируется, модули создаются, но макросы не копируются.

Kadet

И действительно, парадокс.
При первой загрузке библиотека появляется, а макросов нет. И выдаёт кучу ошибок.
В от если всё это закрыть, и закрыть фоновый документ (главную БД), который остаётся после закрытия формы.
А потом снова открыть БД, то всё работает... Парадокс.

Сплошные парадоксы не понятные. Почему, если перенести разблокирование библиотеки из IF  ближе к LoadLibrary он начинает работать? Почему при первой загрузке макросов не видно, а при повторной они появляются? Они не успевают загрузиться? Попробую поставить wait

bk

Цитата: Kadet от 22 августа 2020, 19:53Почему при первой загрузке макросов не видно, а при повторной они появляются? Они не успевают загрузиться? Попробую поставить wait

у меня в Вашем файле с первого раза видны макросы в модулях, но сначала картинка "Без модуля", т.е. появляются они действительно с задержкой где-то в полсекунды.
и что за ошибка выскакивает в LoadLibrary? Зачем там обработчик ошибки, все работает...

Kadet

Цитата: bk от 22 августа 2020, 20:28и что за ошибка выскакивает в LoadLibrary? Зачем там обработчик ошибки, все работает...
Этот вопрос обсуждали ТУТ.

Kadet

Цитата: bk от 22 августа 2020, 20:28у меня в Вашем файле с первого раза видны макросы в модулях,
Проверю на другой машине в понедельник.

bk

Есть ньюанс в использовании допмакроса в этом конкретном примере: согласно справки метод verifyLibraryPassword если уже вызывался ранее, второй вызов дает ошибку. Т.е., если в допмакросе Вы уже распаролили библиотеку, то в ThisDBDoc строчка кода с этим методом выдаст ошибку (com::sun::star::lang::IllegalArgumentException).

Цитата: Kadet от 22 августа 2020, 20:48и что за ошибка выскакивает в LoadLibrary? Зачем там обработчик ошибки, все работает...
Этот вопрос обсуждали ТУТ.

я имею ввиду обработку ошибки в допмакросе в Standard, как Вы написали:
Цитата: Kadet от 22 августа 2020, 19:42Сначала выдавал ошибку в CallLoadLib()