Javascript MSI Automation - закрытие базы данных - PullRequest
1 голос
/ 27 апреля 2009

Я поддерживаю некоторые сценарии сборки, которые восстанавливают базы данных MSI из файлов Javascript (.js). Код в основном:

{
    var oTargetDB = g_oInstaller.openDatabase("mymsi.msi", msiOpenDatabaseModeReadOnly);
    var oView = oTargetDB.openView(...);
    oView.execute();
    oView.close();
}
// Later...
{
    var oTargetDB = g_oInstaller.openDatabase("mymsi.msi", msiOpenDatabaseModeTransact);
}

Вторая openDatabase завершается неудачно с очень полезным 0x80004005 (E_FAIL), который, как я полагаю, потому что первый не закрыт. Однако объект Database не имеет метода close. Я попытался oTargetDB = null - ничего не изменилось.

Что я могу сделать, чтобы закрыть базу данных, чтобы я мог открыть ее снова?

Edit:

  • Я вижу дескриптор, открытый с помощью handle.exe от sysinternals, так что это определенно проблема
  • Задержка не помогла (я пытался ждать очень долго, и это не помогло)
  • Кратковременный сценарий недоступен из-за существующей структуры сценария
  • Uber-хакерство выходит за рамки этого исправления
  • Мне придется увеличить код и перейти к решению (псевдо-синглтон). Blergh.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2009

В этом случае MS забыла реализовать метод close. В самом деле. Хм, да? В общем, установка obj = null не выполняет очистку, такую ​​как операции закрытия.

Когда я столкнулся с этой проблемой, он вызывал объекты MSIDatabase из C #. База данных должна быть закрыта (см. MsiOpenDatabase и MsiCloseHandle ). К сожалению, как вы заметили, MS забыла реализовать Database.Close в COM-объекте, который вы видите. Из C # я смог вызвать Marshal.FinalReleaseComObject , чтобы разблокировать файл.

Мы равномерно отказались от COM-объекта как ненадежного и переключились на p / invoke.

Если jscript - ваш единственный вариант, вы можете продлить сценарии на короткое время - когда они умирают, они освобождают свои дескрипторы. Или вы создаете синглтон для представления объекта. Потенциально, некоторые uberhacker будут знать, как вызвать MsiCloseHandle из jScript, и идентифицировать дескриптор, используемый этим COM-объектом.

0 голосов
/ 28 апреля 2009

Установка дескриптора на ноль работает с VB Script, поэтому я не уверен, почему это не будет с JS. Моим лучшим предположением может быть то, что вы обнаружили ошибку в имплементации JS - особенно если вы открываете ее только для чтения в первый раз, нет необходимости вызывать метод Commit для сброса любых изменений .

Документация , похоже, указывает на то, что простое закрытие дескриптора - это все, что необходимо для закрытия базы данных. Таким образом, я предполагаю, что даже после установки oTargetDB = null Javascript не освобождает дескриптор, когда вы снова открываете его. Вы можете попробовать вставить задержку после освобождения ручки, чтобы увидеть, так ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...