Сообщений 0    Оценка 235 [+1/-0]         Оценить  
Система Orphus

Технология Windows Installer

Часть II - Процесс установки

Автор: Алифанов Андрей
The RSDN Group

Источник: RSDN Magazine #1-2004
Опубликовано: 15.08.2004
Исправлено: 10.12.2016
Версия текста: 1.0
Предисловие
Установка Windows Installer
Instmsi.exe
Msiexec.exe
Механизм установки
Высокоуровневые операции
Таблицы управления последовательностью инсталляции
Механизм запуска инсталляционного пакета
Фазы инсталляционного процесса
Сбор информации
Считывание свойств
Выполнение последовательности InstallUISequence
Выполнение установки
Выполнение последовательности InstallExecuteSequence
Откат
Заключение
Источники информации

Предисловие

В первой части цикла был дан общий обзор технологии Windows Installer. В данной статье я хочу рассмотреть конкретную тему, связанную с данной технологией, а именно процесс установки приложения на компьютер. Какие процессы при этом происходят, какие программы запускаются, какие таблицы пакета инсталляции используются и как они влияют на процесс.

Но, прежде всего, посмотрим, как же устанавливается сам Windows Installer и из каких компонентов он состоит.

Установка Windows Installer

Instmsi.exe

Каждое приложение, использующее Windows Installer, при запуске должно проверить, есть ли уже все необходимое на данном компьютере и если нет, готов ли пользователь и компьютер к установке Windows Installer. Для установки нужной версии используется файл instmsi.exe, доступный с сайта Microsoft. Этот файл содержит все необходимое для установки Windows Installer на компьютер, но должен использоваться только в составе пакета инсталляции (так называемый самоустанавливающийся пакет инсталляции или bootstrapping application). При старте такой пакет, как уже говорилось, проверяет наличие и версию Windows Installer на компьютере. Если Windows Installer не установлен или установлена более старая версия, пакет определяет версию операционной системы, чтобы определить необходимую версию instmsi.exe. После того как процесс установки Windows Installer запущен, самоустанавливающийся пакет должен обрабатывать все коды возврата instmsi.exe и управлять всеми перезагрузками, требующимися при установке Windows Installer. После установки необходимой версии Windows Installer устанавливается собственно тот продукт, для которого инсталляционный пакет и разрабатывался.

Для чего нужен такой самоустанавливающийся пакет? Нужен он в двух случаях:

В системе вообще еще не установлено никакой версии Windows Installer. Этот случай в наше время очень редко встречается, но, тем не менее, может быть и такое.

В системе установлена версия Windows Installer, в которой отсутствуют нужные для работы нашего пакета функции. Попросту говоря, более старая версия. Рассмотрим пример: пакет инсталляции ГИС «Вега» использует в своей работе возможности Windows Installer 2.0. Пользователь хочет установить этот пакет в системе Windows98SE, в которой на данный момент установлен Windows Installer версии 1.1. При запуске наш инсталляционный пакет определит, что необходимо обновить версию Windows Installer и выполнит обновление, а затем продолжит инсталлирование ГИС «Вега».

К сожалению, все не так просто, как хотелось бы. Некоторые версии instmsi.exe и Windows несовместимы, поэтому ниже даны две таблицы, с помощью которых можно определить, какую версию Windows Installer и где можно устанавливать. Стоит отметить, что на данный момент (в связи с почти повсеместным переходом на Windows XP) эта информация уже не так актуальна, как раньше. Кроме того, есть некоторые основания полагать, что отныне все обновления версий Windows Installer будут проводиться синхронно с обновлениями ОС. Например, версию Windows Installer 3.0 планируется выпустить с SP2 для Windows XP, а версию 4.0 – с Longhorn. Так ли это на самом деле, покажет время.

Версия продукта Версия Описание
Windows Installer 1.0 1.00.5104.0 Выпущена с Office2000 и как дистрибутив
Windows Installer 1.1 1.10.1029.0 Выпущена с Windows 2000
1.10.1029.1 Дистрибутив
Windows Installer 1.11 1.11.1314.0 Выпущена с Windows 2000 SP1
Windows Installer 1.2 1.20.1410.0 Выпущена с Windows Me
1.20.1827.1 Дистрибутив
Windows Installer 2.0 2.0.2600.0 Выпущена с Windows XP
2.0.2600.1 Выпущена с Windows 2000 SP3
2.0.2600.2 Дистрибутив
2.0.2600.1106 Выпущена с Windows XP SP1
2.0.3754.0 или позже Выпущена с семейством Windows Server 2003
Таблица 1. Версии Windows Installer.
Если instmsi устанавливает следующую версию Windows Installer Этот instmsi может быть запущен в следующих ОС Этот instmsi не должен запускаться в следующих ОС
Windows Installer 1.0 Windows 95, Windows 98, Windows NT 4.0 + SP3 Windows Me, Windows 2000, Windows XP
Windows Installer 1.1 Windows 95, Windows 98, Windows NT 4.0 + SP3 Windows Me, Windows 2000, Windows XP
Windows Installer 1.2 Windows 95, Windows 98, Windows Me, Windows NT 4.0 + SP3 Windows 2000, Windows XP
Windows Installer 2.0 Windows 95, Windows 98, Windows Me, Windows NT 4.0 + SP6, Windows 2000 Windows XP
Таблица 2. Версии Instmsi.exe.

То есть, если приложение устанавливает Windows Installer версии 1.1, оно должно убедиться, что работает под ОС Windows NT 4.0 с SP3 или Windows 95/98. Также необходимо помнить, что под Windows95/98 нужно устанавливать ANSI версию, а под Windows NT или Windows 2000 – Unicodeверсию Windows Installer.

Как можно понять из этой таблицы, любую более новую версию Windows Installer можно устанавливать в системах, не имеющих Windows Installer вообще или имеющих более раннюю версию. Исключение сделано только для версии 1.2. Немного странно, что Windows Installer версии 1.2 нельзя устанавливать на систему Windows 2000. Я не знаю точно, с чем это связано, но, судя по некоторым фразам из MSDN можно сделать вывод, что эта версия использует возможности защиты системных файлов в реализации для WindowsMe, несовместимые с аналогичными функциями в Windows 2000. Будем надеяться, что подобное не повторится с будущими версиями Windows Installer.

Многие приложения, распространяющие instmsi, переименовывают ANSI-версию файла в instmsia.exe, а Unicode-версию – в instmsiw.exe.

InstallShield Developer, например, в случае использования самоустанавливающегося пакета, создает три файла: setup.exe, instmsia.exe и instmsiw.exe. Файл setup.exe содержит всю логику проверки требований к ОС и запуска соответствующей версии instmsi. Файлы instmsi*.exe, в свою очередь, содержат ту версию Windows Installer, которую выбрал разработчик инсталляционного пакета.

Опция Описание
/q Для использования в приложениях, которые устанавливают Windows Installer. Не предоставляется никакого пользовательского интерфейса.
/t Используется только для отладки.
/c:"msiiinst /delayreboot" Отложенная перезагрузка.
/c:"msiiinst /delayrebootq" "Молчаливая" версия отложенной перезагрузки. Отличается от предыдущей версии только полным отсутствием сообщений для пользователя.
/? Вызов справки.
Таблица 3. Опции командной строки instmsi.exe.
ПРИМЕЧАНИЕ

Современные версии средств создания инсталляционных пакетов (таких как InstallShield Developer или WiseInstaller) позволяют скрыть от разработчика детали создания самоустанавливающихся приложений. Все, что обычно нужно сделать: указать нужную версию Windows Installer, остальное эти средства выполнят сами – вам останется только наслаждаться результатами.

Файл instmsi.exe содержит в себе архив с несколькими .exe и .dll-файлами. Самым важным среди этих файлов является msiexec.exe. Что это за программа и для чего она нужна, будет рассмотрено дальше.

Msiexec.exe

Если быть более точным, msiexec.exe – не самый важный компонент в Windows Installer. Всю основную работу делает динамически подключаемая библиотека – msi.dll. А msiexec.exe служит лишь оболочкой для того, чтобы:

  1. Позволить Windows Installer работать как службе в ОС Windows NT/2000/XP, и как обычному приложению – в ОС Windows 9x.
  2. Разбирать параметры командной строки и выполнять соответствующие задачи.
  3. Устанавливать при выходе уровень ошибки, соответствующий системным кодам ошибок (то есть ошибкам типа ERROR_SUCCESS и т.д.)
  4. Связать файлы с расширениями .msi с Windows Installer – таким образом, двойной щелчок мышью в Explorer на файле your_product.msi приведет к запуску msiexec.exe со следующими параметрами: "%SystemRoot%\System32\msiexec.exe" /i "your_product.msi"

Опции командной строки, которые понимает msiexec, приведены в таблице . В таблице перечислены далеко не все опции, а только те, которые связаны с темой данной статьи.

Опция Параметры Значение
/I Код пакета / продукта Установить или конфигурировать приложение
/f [p|o|e|d|c|a|u|m|s|v]Код пакета / продукта Восстановить приложение. Если задана эта опция, msiexec игнорирует значения свойств, заданные в командной строке. Список по умолчанию для данной опции pecms. p – Переустановить, только если файл отсутствует.o – Переустановить, если файл отсутствует или установлена более старая версия.e – Переустановить, если файл отсутствует или установлена такая же либо более старая версия.d – Переустановить, если файл отсутствует или установлена другая версия.c – Переустановить, если файл отсутствует или его сохраненная контрольная сумма не соответствует вычисленному значению. Переустанавливаются только файлы с установленным атрибутом msidbFileAttributesChecksum в поле Attributes таблицы File.a – Переустановить все файлы.u – Перезаписать все необходимые специфичные для пользователя ключи реестра.m – Перезаписать все необходимые специфичные для машины ключи реестра.s – Перезаписать все существующие ярлыки.v – Запустить с исходного носителя и заново кэшировать локальный пакет.
/a Пакет Опция Административной установки. Установить продукт в сети.
/x Код пакета / продукта Деинсталлировать продукт.
/j [u|m]Пакетили[u|m]Пакет /g Идентификатор языка Опубликовать продукт. Если задана эта опция, msiexec игнорирует значения свойств, заданные в командной строке.u – Опубликовать для текущего пользователя.m – Опубликовать для всех пользователей компьютера.g – Идентификатор языка.
/q n|b|r|f Задать уровень пользовательского интерфейса (ПИ).q, qn – отсутствие ПИ. В этом случае не показывается никаких окон и не задается никаких вопросов. Данный режим очень удобен для автоматической инсталляции ПО.qb – уровень базового пользовательского интерфейса.qr – уровень сокращенного пользовательского интерфейса.qf – уровень полного пользовательского интерфейса.
Таблица 4. Опции командной строки msiexec.exe.

В ОС на ядре Windows NT msiexec.exe запускается как служба с недокументированным параметром /V. Причем служба конфигурируется как Запускаемая вручную (по требованию).

Кроме того, в командной строке можно задавать значения для открытых (public) свойств инсталляционного пакета.

Чтобы установить пакет Example.msi с диска a:, используйте следующий синтаксис:

msiexec /i A:\Example.msi

Чтобы установить пакет Example.msi с диска a: и задать свойство PROPERTY, используйте следующий синтаксис:

msiexec /i A:\Example.msi PROPERTY=VALUE
msiexec /i A:\Example.msi PROPERTY="Строка с пробелами"
msiexec /i A:\Example.msi PROPERTY="Строка с пробелами и ""вложенными"" кавычками"
msiexec /i A:\Example.msi PROPERTY=""

Последний пример – очистка значения свойства.

Само собой разумеется, что запускать msiexec.exe вручную и задавать имя файла инсталляционного пакета совсем необязательно. Это требуется только в том случае, если нужно изменить значения каких-то свойств или задать дополнительные параметры. Если же вас устраивают параметры по умолчанию – достаточно дважды щелкнуть в Проводнике Windows на нужном файле .msi или набрать в командной строке start example.msi – и запустится установщик программного продукта.

На этом можно закончить с установкой и составом Windows Installer и перейти к рассмотрению вопросов о внутренних механизмах работы инсталлятора.

Механизм установки

Как можно понять из таблицы опций командной строки, инсталлятор может работать в следующих режимах:

ПРИМЕЧАНИЕ

На самом деле есть еще несколько режимов работы (например, обновления продукта и преобразования). Но они в данной статье рассматриваться не будут.

Высокоуровневые операции

Этим режимам соответствуют три высокоуровневые операции, выполняемые Windows Installer: INSTALL, ADMIN и ADVERTISE. Почему только три? Потому что каждая из этих операций включает в себя всю логику для инсталляции, деинсталляции и восстановления приложения.

Операция INSTALL

Эта операция используется для установки и удаления компонентов программного продукта. При выполнении этой операции используются запросы к таблицам InstallUISequence и InstallExecuteSequence. Эта операция не хранится в базе данных пакета инсталляции, а выполняется при вызове метода MsiInstallProduct, при вызове msiexec.exe с параметром /i, а также при вызове любых функций API Windows Installer, которые могут выполнять инсталляцию компонентов, например, MsiConfigureFeature, MsiProvideComponent или MsiInstallMissingFile.

Операция ADMIN

Эта операция используется для административной установки приложения. При выполнении этой операции используются запросы к таблицам AdminUISequence и AdminExecuteSequence. Эта операция также не хранится в базе данных пакета инсталляции, а выполняется при вызове метода MsiInstallProduct с параметром szCommandLine "ACTION=ADMIN" или при вызове msiexec.exe с параметром /a.

Что же представляет собой административная установка? Это установка продукта на какой-либо из машин сети для использования группой пользователей. При этом на сервере создается инсталляционный пакет, практически идентичный исходному пакету на CD-ROM. Пользователи, имеющие доступ к этому пакету, затем могут установить продукт и использовать его. Одним из преимуществ такого типа установки является возможность для пользователей установить только минимально необходимую для работы часть продукта, оставив все остальное на сервере. Таким образом, экономится место на локальных дисках пользователей и облегчается обновление продукта, так как во многих случаях достаточно обновить только разделяемую часть продукта, хранящуюся на сервере.

Операция ADVERTISE

Эта операция используется для установки и удаления опубликованных компонентов программного продукта. При выполнении этой операции используются запросы к таблице AdvtExecuteSequence. Эта операция также не хранится в базе данных пакета инсталляции, а выполняется при вызове метода MsiInstallProduct с параметром szCommandLine "ACTION=ADVERTISE" или при вызове msiexec.exe с параметром /j.

Таблицы управления последовательностью инсталляции

Все таблицы управления последовательностью инсталляции имеют одинаковую структуру и состоят из трех полей: Action, Condition и Sequence. Поле Action может задавать одно из следующих имен: имя стандартной или пользовательской операции, или имя диалогового окна. Поле Condition позволяет разработчику инсталляционного пакета задать логическое выражение для управления выполнением операции или отображением пользовательского диалогового окна. Если поле пустое или выражение в нем равно True, требуемая операция выполняется. В противном случае операция пропускается, а диалог не показывается. Поле Sequence задает порядок выполнения операций и отображения диалогов в последовательности. Таким образом, чем больший номер имеет операция или диалог, тем позже они выполняются.

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

Таблицы последовательности пользовательского интерфейса обычно содержат стандартные операции, позволяющие пользователю получить и изменить информацию, необходимую для инсталляции продукта. Последовательность отображения диалогов пользовательского интерфейса соответствует порядку записей в таблице Dialog. Имена диалогов в этой таблице связаны с полем Action соответствующей таблицы последовательности. Таким образом, пользователь получает возможность принять или изменить информацию и начать процесс инсталляции, который начинается вместе с началом обработки соответствующей таблицы последовательности выполнения.

Механизм запуска инсталляционного пакета

Прежде чем рассматривать фазы инсталляционного процесса, я позволю себе рассмотреть механизмы запуска инсталляционного пакета. Во-первых, под ОС Windows NT и ее наследницами это происходит довольно интересным образом, а во-вторых, знание этих механизмов поможет в рассмотрении фаз.

Итак, как я уже упоминал, в этих ОС msiexec.exe работает как служба. Причем служба запускается по требованию. Для чего это нужно? Дело в том, что когда вы запускаете инсталляционный пакет, вы запускаете его от своего имени (или от имени другого пользователя, с более широкими полномочиями). При этом запускается копия msiexec.exe, которая будет выполнять все действия, связанные с обработкой пользовательского интерфейса, предоставляемого данным инсталляционным пакетом. Эта копия, в свою очередь, активизирует службу, которая работает уже не от имени вашей учетной записи, а от имени записи System, обладающей, как известно, практически неограниченными правами. Именно эта копия msiexec.exe (а также запускаемые ее при необходимости дополнительные процессы) и будет выполнять собственно установку приложения – копировать файлы, обновлять записи в реестре и т.д. Таким образом, обеспечивается дополнительный уровень безопасности.

Любопытно, что после завершения процесса инсталлирования программного продукта системная копия msiexec.exe не выгружается, а остается в памяти. При этом последующие инсталляционные процессы (буде таковые инициируются) будут использовать ее, а не создавать новые копии.

Таким образом, инсталлирование вашего программного продукта производится как минимум двумя (а то и больше – если есть вложенные инсталляции) процессами.

Фазы инсталляционного процесса

Итак, наконец-то мы добрались до самого интересного, до фаз инсталляционного процесса.

На самом общем уровне во всех режимах можно выделить две фазы инсталляционного процесса: сбор информации (Acquisition) и собственно выполнение установки (Execution). При этом, если процесс инсталляции по каким-либо причинам завершился неудачно, появляется еще одна фаза: откат.

Сбор информации

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

Выполнение установки

Во время этой фазы инсталлятор передает информацию процессу с расширенными правами (системной службе, работающей с правами System), необходимыми для выполнения установки приложения, и запускает скрипт, сгенерированный на предыдущем этапе.

Откат

Если процесс инсталляции по каким-либо причинам завершается неудачно (например, в процессе установки выяснилось, что на исходном носителе нет нужных файлов – ситуация нередкая на пиратских дисках), инсталлятор приводит систему в исходное состояние. Когда инсталлятор генерирует инсталляционный скрипт, одновременно он создает и скрипт для отката. К тому же, инсталлятор сохраняет копию каждого файла, удаляемого в процессе инсталляции. Эти файлы хранятся в скрытом системном каталоге. После успешного завершения инсталляции скрипт для отката и сохраненные файлы удаляются.

Каждая из фаз далее будет рассмотрена подробно.

Итак, приступим к рассмотрению последовательности операций, выполняемых Windows Installer при установке типичного приложения. В качестве примера я возьму инсталляционный пакет, сгенерированный с помощью InstallShield Developer версии 8.0. Как вы уже знаете, инсталляционный пакет состоит из множества связанных между собой таблиц, организованных в реляционную базу данных. Так как я буду рассматривать типичный процесс инсталляции, в качестве основных таблиц будут использованы InstallUISequence и InstallExecuteSequence. Последовательности, используемые при административной установке и публикации приложения, проще и рассматриваться здесь не будут.

Сбор информации

Считывание свойств

Прежде всего при запуске инсталляционного пакета Windows Installer считывает из базы данных все свойства и если необходимо, модифицирует их значениями, полученными из командной строки.

ПРИМЕЧАНИЕ

На самом деле, я не уверен, что это делается сразу. Вполне возможно, что этот процесс откладывается до проверки условия LaunchConditions. Но для простоты будем считать, что это происходит так, как сказано выше.

Выполнение последовательности InstallUISequence

Затем Windows Installer считывает последовательность операций из таблицы InstallUISequence и начинает их выполнять.

Из этого правила есть исключение: если установка выполняется в «тихом» режиме, таблица InstallUISequence не обрабатывается. Об этом будет сказано подробнее при рассмотрении таблицы InstallExecuteSequence.

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

Action (Операция) Condition (Условие) Sequence(Последовательность)
SetupCompleteError -3
SetupInterrupted -2
SetupCompleteSuccess -1
AppSearch 400
LaunchConditions 410
SetupInitialization 420
FindRelatedProducts 430
CCPSearch CCP_TEST 500
RMCCPSearch Not CCP_SUCCESS And CCP_TEST 600
ValidateProductID 700
CostInitialize 800
FileCost 900
ResolveSource Not Installed And Not PATCH 990
CostFinalize 1000
MigrateFeatureState 1200
PatchWelcome PATCH And Not IS_MAJOR_UPGRADE 1205
InstallWelcome Not Installed And (Not PATCH Or IS_MAJOR_UPGRADE) 1210
SetupResume Installed And (RESUME Or Preselected) And Not PATCH 1220
MaintenanceWelcome Installed And Not RESUME And Not Preselected And Not PATCH 1230
SetupProgress 1240
ExecuteAction 1300
Таблица 5.

Краткая информация об операциях Windows Installer

Все операции в таблице последовательностей выполняются по порядку, определяемому номером (третье поле таблицы). Номера должны быть положительными целыми числами. Microsoft рекомендует при заполнении таблиц последовательностей оставлять промежутки между номерами, чтобы при необходимости можно было добавить операцию без перенумерации остальных. Кроме того, стандартные операции должны иметь номера, кратные десяти. Номера пользовательских операций, напротив, не должны быть кратны десяти.

Как же так, номера операций должны быть положительными, а в самом начале таблицы можно увидеть три операции с отрицательными номерами? Ничего удивительного здесь нет: на самом деле номер у операции может быть любой. Но выполняться будут только операции с положительными номерами. Для операций с отрицательными номерами определены только четыре значения (от -4 до -1) – эти операции выполняются только в том случае, если Installer вернул соответствующий флаг завершения установки из приведенной ниже таблицы.

Флаг завершения Значение Описание
msiDoActionStatusSuccess -1 Установка успешно завершена
msiDoActionStatusUserExit -2 Установка прервана пользователем
msiDoActionStatusFailure -3 В процессе установки произошла непоправимая ошибка
msiDoActionStatusSuspend -4 Установка приостановлена
Таблица 6.

Все остальные отрицательные значения, а также 0, означают операцию, которая никогда не выполняется.

Имена операций подчиняются следующим правилам. Так как в таблицах управляющих последовательностей нет никакой информации о типах операций, Windows Installer работает по следующему алгоритму:

Тема стандартных и пользовательских операций Windows Installer заслуживает отдельной статьи, поэтому я позволю себе продолжить рассмотрение механизма их выполнения, не вдаваясь в детали. Подробно здесь будут рассмотрены только операции, присутствующие в таблицах последовательностей и те таблицы и операции, которые с ними связаны.

Операция AppSearch

Итак, первым делом инсталлятор выполняет операцию AppSearch. Эта операция, как и следующая за ней LaunchConditions является необязательной для работы инсталляционного пакета. Но, тем не менее, она может быть весьма полезна, если перед запуском необходимо удостовериться в наличии или отсутствии на компьютере какой-либо определенной программы или просто какого-нибудь файла. В поиске обязательно участвуют таблица Signature и одна или несколько из следующих таблиц: CompLocator, RegLocator, IniLocator и, наконец, DrLocator. Про назначение этих таблиц я говорил в первой статье (см. RSDN Magazine #3’2002). Здесь же я хочу подробно показать пример поиска предыдущей версии программы. Для примера я возьму поиск некой ГИС «Вега» версии 1.0.

Поиск в данном случае ведется в два этапа: сначала находятся нужные записи в реестре. При этом обрабатываются таблицы AppSearch, Signature и RegLocator. В таблице AppSearch берется запись с сигнатурой sigVegaRegistry, в таблице RegLocator ищется запись с такой же сигнатурой и затем ищется запись в реестре, заданная полем RegLocator.Key. В моем случае это поле содержит строку вида CLSID\{F55AD342-DAE2-11d2-B91E-0080AD190F7E}\LocalServer32. Если такая запись в реестре найдена, то свойству OLDVEGAPATH присваивается значение, взятое из реестра. В данном случае это будет что-то типа C:\Program Files\AIST\Vega\Vega.exe. Если же записи в реестре нет, значение свойства будет не определено.

Ниже показано содержимое таблиц, участвующих в данном поиске.

Property Signature_
OLDVEGAPATH sigVegaRegistry
Таблица 7. Таблица AppSearch.
Signature FileName
sigVegaRegistry FileName
Таблица 8. Таблица Signature.
ПРИМЕЧАНИЕ

В этой таблице гораздо больше полей, но в данной операции они не участвуют и поэтому здесь не показаны.

Signature_ Root Key Name Type
sigVegaRegistry 0 CLSID\{F55AD342-DAE2-11d2-B91E-0080AD190F7E}\LocalServer32 1
Таблица 9. Таблица RegLocator.
ПРИМЕЧАНИЕ

Поле Root задает ветвь реестра, в которой должен вестись поиск. В данном случае – HKEY_CLASSES_ROOT.

Поле Name задает имя параметра реестра, значение которого нужно прочитать. Если это поле не заполнено, возвращается значение параметра по умолчанию.

Поле Type задает тип параметра реестра, а именно, задает ли он имя файла, каталога или имеет какое-то другое значение. В данном случае тип параметра – имя файла.

Если сигнатуры каких-либо файлов не описаны в таблице Signature, считается, что они описывают каталоги, а не файлы.

Следующий шаг: проверка свойства OLDVEGAPATH. Если это свойство не определено – поиск прекращается, и процесс инсталляции продолжается. При этом считается, что старой версии ПО на компьютере нет. В противном случае ищется ядро ГИС, представляющее собой исполняемый файл формата PE. В поиске используются таблицы: AppSearch, Signature и DrLocator.

Содержимое таблиц для данного этапа поиска показано ниже.

Property Signature_
OLDVEGAFOUND sigVegaFile
Таблица 10. Таблица AppSearch.
Signature FileName MinVersion MaxVersion
sigVegaFile Vega.exe 1.9.9999.9999
Таблица 11. Таблица Signature
ПРИМЕЧАНИЕ

Остальные поля этой таблицы в данной операции не используются и поэтому здесь не показаны.

Signature_ Parent Path Depth
sigVegaFile sigVegaRegistry 0
Таблица 12. Таблица DrLocator.
ПРИМЕЧАНИЕ

Поле Parent определяет родительский каталог для файла или каталога, заданного в поле Signature_. Если это поле пустое и поле Path не содержит полный путь, то в операцию поиска вовлекаются все локальные диски. В данном случае это поле связано с записью в таблице RegLocator и содержит полный путь к файлу.

Поле Path содержит путь на пользовательской машине. Это поле может содержать полный путь или относительный путь в каталоге, заданном полем Parent.

Поле Depth определяет максимальную глубину поиска в подкаталогах относительно пути, заданного в поле Path.

Как можно понять из приведенных выше таблиц, в данном случае ведется поиск файла vega.exe с версией не выше 1.9.9999.9999. Полный путь к этому файлу находится в свойстве OLDVEGAPATH, которому соответствует сигнатура sigVegaRegistry. Этот путь был найден в реестре на предыдущем шаге. Если такой файл найден и все его атрибуты соответствуют заданным в таблице Signature (в данном случае это только максимальный номер версии, хотя критериев поиска может быть гораздо больше), то свойству OLDVEGAFOUND присваивается некоторое значение. Нас не интересует конкретное значение этого свойства, главное, что оно определено, и мы можем его использовать в логических операциях.

Проверяться это свойство будет в следующей операции.

Операция LaunchConditions

Как можно понять из самого названия: назначение данной операции – проверка условий для запуска процедуры инсталляции. При выполнении этой операции Windows Installer проверяет все условия в таблице LaunchCondition. Если эта таблица пуста или значения всех условий равны True – инсталляция продолжается, в противном случае выдается сообщение об ошибке и процесс инсталляции заканчивается.

В нашем случае таблица LaunchCondition содержит всего одну запись.

Condition Description
Not OLDVEGAFOUND Найдена старая версия ГИС 'Вега'. Удалите старую версию и запустите программу установки снова.
Таблица 13.

Если условие в поле Condition не будет выполнено (а это случится, только если найдена старая версия ПО), то пользователь увидит сообщение, заданное в поле Description и процесс инсталляции будет прерван. Мы же будем считать, что старой версии нет и пойдем дальше.

Операция SetupInitialization

Эта операция используется для показа первого диалогового окна инсталляционного пакета. Начиная с этого момента дальнейшие действия инсталляционного пакета будут направляться пользователем с помощью хорошо всем знакомой последовательности «мастеров».

ПРИМЕЧАНИЕ

В инсталляционных пакетах, созданных с помощью стандартных средств, предоставляемых Microsoft, этого диалога нет. В то же время более продвинутые пакеты (такие как, например, Microsoft Office) содержат диалоги аналогичного назначения. И я думаю, что это правильно – инициализация больших и сложных пакетов может занимать длительное время и нехорошо оставлять пользователя в неведении о том, что же в данный момент делается.

При выполнении этой операции (как, впрочем, и при показе других диалогов) используются таблицы Dialog, Control, ControlEvent, EventMapping, TextStyle и Property.

ПРИМЕЧАНИЕ

Я перечислил далеко не все таблицы, так как подробный разбор работы пользовательского интерфейса Windows Installer выходит за рамки данной статьи. Возможно, этому вопросу будет посвящена отдельная статья.

Это окно остается на мониторе пользователя при выполнении последующих операций, вплоть до PatchWelcome.

Операция FindRelatedProducts

Как можно догадаться из названия, данная операция используется для поиска связанного с устанавливаемым ПО. В отличие от предыдущих операций, на данном шаге ищутся только ранее установленные с помощью Windows Installer продукты. При этом производятся запросы к таблице Upgrade, и результаты запросов (а именно, код обновления, версия продукта и язык) сравниваются с данными уже установленных в системе пакетов. Если соответствие найдено, то к значению свойства из поля ActionProperty таблицы Upgrade добавляется код установленного продукта. Свойство, заданное в этом поле, должно быть открытым (иными словами, иметь имя, не содержащее строчных букв).

Эта операция выполняется только при первой установке ПО.

Данная операция очень важна для так называемого «значительного обновления» предыдущих версий, то есть такого обновления, при котором меняется код продукта. Если вы не планируете таких обновлений, данную операцию можно убрать из инсталляционных последовательностей.

В качестве примера я рассмотрю следующий случай: начиная с версии 2.1.378 в составе ПО ГИС «Вега» произошли значительные изменения: добавилось несколько новых компонентов, а некоторые были удалены или переименованы. Это потребовало значительного обновления, так как Windows Installer не позволяет просто так менять структуру инсталляционного пакета. При этом код продукта новой версии был изменен, а код обновления остался прежним.

Код продукта и код обновления – это GUIDы, использующиеся Windows Installer. При этом наличие кода обновления не является обязательным, но иметь его крайне желательно, так как в случае его отсутствия будет невозможно провести обновление существующего ПО. Придется его удалять, а затем ставить новую версию с «чистого» листа – при этом, естественно, многое можно потерять (например, все настройки приложения, хранящиеся в реестре).

UpgradeCode MinVersion MaxVersion Language Attributes Remove ActionProperty
{DD74EC62-8650-4E32-8320-0E50F4BAEDE8} 2.1.377 769 ISACTIONPROP1
Таблица 14 Таблица Upgrade

Я думаю, что назначение полей этой таблицы понятно без объяснений. Исключение составляет только поле Attibutes, о котором я расскажу более подробно.

Это поле содержит набор битовых флагов, определяющих поведение Windows Installer при обновлении продукта. Флаги подробно описаны в MSDN, я же скажу только, что в моем случае число 769 означает: найти приложение с максимальной версией 2.1.377 и минимальной версией 0 (комбинация флагов msidbUpgradeAttributesVersionMinInclusive и msidbUpgradeAttributesVersionMaxInclusive). При этом, если такое приложение будет найдено, отобразить состояние опций установленной версии на состояние опций устанавливаемой версии (флаг msidbUpgradeAttributesMigrateFeatures). Последнее будет более подробно объяснено ниже при рассмотрении операции MigrateFeatureStates.

После выполнения этой операции свойство ISACTIONPROP1 получит значение {96D6AFCD-9509-428B-8F97-688C081FE895} в том случае, если в системе установлена версия не выше 2.1.377. Это означает, что нужно будет выполнить «значительное обновление», в противном случае свойство будет не определено, и инсталляция будет выполняться в обычном режиме.

Операция CCPSearch

Префикс CCP в названии операции означает Compliance Checking Program, то есть проверка соответствующих программ (в смысле: удовлетворяющих каким-либо требованиям). Эта операция выполняется при обновлении программных продуктов. При этом проверяется факт наличия в системе какого-либо продукта или файла. Для поиска продуктов и файлов используются записи в таблице CCPSearch, которые, в свою очередь, ссылаются на записи в таблицах Signature, RegLocator, IniLocator, CompLocator и DrLocator. По большому счету, эта операция во многом дублирует функциональность AppSearch, правда, в отличие от последней, она без лишних вопросов прерывает процесс инсталляции, если не найден продукт, удовлетворяющий заданным требованиям. При этом выдается примерно такое сообщение, мало что говорящее обычному пользователю:

          Не удается найти установленные совместимые продукты для установки данного продукта.

        

К счастью, это сообщение можно переопределить (оно имеет стандартный номер 1608 в таблице Error) и выдать пользователю что-то более осмысленное, например:

          Для установки данного продукта необходимо наличие в системе Microsoft Office XP.

        

Операция RMCCPSearch

Операция RMCCPSearch выполняет поиск нужных продуктов или файлов на сменных носителях информации (префикс RM в данном случае означает removable, то есть сменный). Как можно видеть из таблицы, эта операция выполняется только в том случае, если предыдущая операция закончилась неуспешно (то есть свойство CCP_Success не определено). Для работы операции необходимо, чтобы свойство CPP_DRIVE указывало на корневой каталог сменного носителя информации (например, CD-ROM диска), на котором нужно искать установленный продукт или файл. Операция использует таблицы CCPSearch и DrLocator. Поведение операции аналогично операции CCPSearch. Честно говоря, я затрудняюсь найти для этой операции подходящее применение.

Операция ValidateProductID

Эта операция присваивает свойству ProductID идентификатор программного продукта. Этот идентификатор обычно вводится пользователем в диалоге регистрации, но может также задаваться в командной строке или прямо в таблице Property.

Если вы хотите задавать идентификатор в командной строке, учтите, что в этом случае нужно использовать свойство PIDKEY, а не ProductID. Дело в том, что ProductID по умолчанию имеет вид: 12345-111-1111111-xxxxx, где вместо выделенных единиц можно вводить любые цифры. Символы, обозначенные x, генерируются Windows Installer и пользователю не видны. Пользователь не видит также и первые пять цифр. Свойство PIDKEY содержит только часть идентификатора, вводимую пользователем.Но вы можете задать любую маску и получить нужный идентификатор, присвоив соответствующее значение свойству PIDTemplate. По умолчанию это свойство имеет вид: 12345<###-%%%%%%%>@@@@@.

Не знаю, по какой причине, но InstallShield Developer не использует данное свойство. Вместо него в этом продукте введено свойство с именем ISX_SERIALNUM.

Как вы дальше будете использовать данные свойства ProductID, дело ваше. Windows Installer проверяет только соответствие значения свойства заданной маске, остальное его не интересует.

Операция CostInitialize

Эта операция исключительно важна для работы инсталляционного пакета, так как она инициирует так называемый оценочный процесс (термин мой). Оценочный процесс – это процесс определения дискового пространства, необходимого для установки программного продукта. При этом Windows Installer определяет размер дискового пространства, необходимого для устанавливаемых и удаляемых файлов ПО, записей в реестре, ярлыков и прочих вспомогательных файлов. Кроме всего прочего, здесь определяется список файлов, которые необходимо обновить.

ПРИМЕЧАНИЕ

Да-да, я не ошибся – и для удаляемых файлов тоже. Это связано с возможностью отката неудавшегося процесса, так как информация, необходимая для отката, хранится на диске. Впрочем, об этом позже.

Общая оценка выполняется покомпонентно и состоит из трех отдельных частей: оценки размера локальных, исходных и удаляемых данных. Этим оценкам соответствуют следующие состояния компонентов: устанавливается локально, запускается с исходного носителя или удаляется.

При выполнении этой операции таблицы Component и Feature загружаются в память и обрабатываются.

Операция FileCost

Эта операция должна вызываться сразу после операции CostInitialize и служит для выполнения динамической оценки дискового пространства. Что при этом происходит? В память загружается таблица File и все записи этой таблицы последовательно начинают проверяться. При этом Windows Installer определяет, нужно ли переписывать уже существующие файлы. По умолчанию выполняется сравнение версий файлов. Если уже существующий в системе файл имеет версию не меньшую, чем устанавливаемый, то замещения файлов не происходит и занимаемое файлом дисковое пространство не учитывается. В любом случае, результат проверки используется инсталлятором для задания состояний каждого из файлов.

1. С помощью ключей командной строки и свойства REINSTALL можно изменить поведение инсталлятора при замещении уже существующих файлов.

2. Данная операция только начинает процесс оценки. Реальная оценка выполняется только в операции CostFinalize.

Операция ResolveSource

Эта операция используется для определения местоположения исходных данных инсталляционного пакета (файла .msi). При этом путь к исходному файлу присваивается свойству SourceDir, в том случае, если оно еще не определено. Эта операция должна вызываться до первого использования свойства в логических выражениях. Кроме того, эта операция не должна вызываться, если источник недоступен (например, при деинсталляции приложения). Если мы еще раз посмотрим в таблицу операций, то увидим, что операция вызывается только при выполнении следующего условия: Not Installed And Not PATCH. Фактически это означает, что она вызывается только при первой установке программного продукта.

Операция CostFinalize

Как можно понять из названия, эта операция заканчивает оценочный процесс, начатый операцией CostInitialize. При этом загружается в память и обрабатывается таблица Condition. По результатам обработки этой таблицы определяются те опции приложения, которые будут установлены (смотри п.2 примечания к операции FileCost).

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

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

Операция MigrateFeatureStates

Данная операция используется при обновлении программных продуктов. Эта операция читает состояния опций уже установленного приложения (вся информация в текущей версии Windows Installer хранится в реестре Windows) и устанавливает состояния соответствующих опций устанавливаемого приложения. Само собой, что данная операция имеет смысл только в том случае, если структуры приложений отличаются незначительно. Эта операция выполняется только один раз, при первой установке.

Windows Installer при выполнении этой операции считывает в память и обрабатывает таблицу Upgrade, которую я уже разобрал при рассмотрении операции FindRelatedProducts. Поэтому не буду на ней останавливаться. При этом инсталлятор читает каждую запись из таблицы и сравнивает код обновления, версию продукта и язык с таковыми у каждого из установленных в системе продуктов. При нахождении соответствия инсталлятор читает состояния опций уже установленного приложения и устанавливает опции нового приложения.

1. Эта операция выполняется только в том случае, если не задано свойство Preselected. Данное свойство означает, что опции уже выбраны и в показе диалога для их выбора нет необходимости. Windows Installer устанавливает это свойство в «1» при возобновлении прерванной установки, а также при задании некоторых глобальных опций типа ADDLOCAL или REMOVE в командной строке.

2. Операция должна вызываться сразу после CostFinalize.

3. Если какая-то из опций относится к нескольким приложениям, состояние опций может быть различным для каждого из них. В этом случае используется следующий порядок определения состояния: устанавливать локально, запускать с исходного носителя, опубликовать, и, наконец, удалить.

Следующие операции PathWelcome, InstallWelcome, SetupResume и MaintenanceWelcome являются взаимоисключающими, то есть при каждом запуске процесса инсталляции выполняется только одна из них. Какая из операций будет выполнена, зависит от выполнения условий в поле Condition таблицы InstallUISequence.

Операция PatchWelcome

Эта операция выполняется, когда условие PATCH And Not IS_MAJOR_UPGRADE становится равным True. Это означает, что необходимо установить программу-заплату, то есть, иными словами, исправить мелкие ошибки в существующем программном продукте.

Операция InstallWelcome

Эта операция выполняется при соблюдении условия Not Installed And (Not PATCH Or IS_MAJOR_UPGRADE), то есть при первой установке программы. Операция представляет собой последовательность диалоговых окон, направляющих действия пользователя и позволяющих получить от него всю необходимую для установки приложения информацию.

Операция SetupResume

Эта операция выполняется при соблюдении следующих условий: Installed And (RESUME Or Preselected) And Not PATCH, то есть при возобновлении прерванного по какой-либо причине процесса инсталляции.

Операция MaintenanceWelcome

Эта операция выполняется, когда пользователь изменяет опции уже установленного приложения, удаляет или переустанавливает его. При этом выполняется следующее условие: Installed And Not RESUME And Not Preselected And Not PATCH.

Операция SetupProgress

Эта операция опять же на самом деле представляет собой диалоговое окно, в котором только отображается процесс установки приложения. Вся реальная работа делается в последовательности InstallExecuteSequence.

Операция ExecuteAction

Эта операция инициирует процесс собственно установки приложения на компьютер. При этом инсталлятор использует значение свойства EXECUTEACTION для определения реального типа установки. Это свойство задает одну из рассмотренных ранее высокоуровневых операций: INSTALL, ADVERTISE и ADMIN.

Операция выполняется с системными привилегиями, если разрешено выполнение службы Windows Installer.

Похоже, что последовательность выполнения, заданная в таблице InstallUISequence, вещь весьма условная. По крайней мере, это верно в отношении данной операции: с одной стороны, она стоит на последнем месте в последовательности, а с другой – выполняется одной из первых. Более того, эта операция вообще может отсутствовать в таблице InstallUISequence, в этом случае Windows Installer считает, что она стоит последней в списке. Но если эта операция есть, она действительно должна быть последней, а иначе возможны неприятности в процессе установки приложения.

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

Я хотел привести примерную временную диаграмму выполнения процесса инсталляции, но пришлось отказаться от этой мысли, слишком запутан процесс.

Выполнение установки

Итак, настало время рассмотреть последовательность InstallExecuteSequence. Операции этой последовательности выполняются параллельно (начиная с некоторого момента) с операциями последовательности InstallUISequence. В то же время эта последовательность является самодостаточной и содержит полный набор операций, необходимых для установки приложения. Связано это с тем, что если установка выполняется в «тихом» режиме, то операции, ответственные за сбор информации (считывание свойств, сопоставление их со значениями из командной строки и другие операции), выполняются в контексте таблицы InstallExecuteSequence. Соответственно, многие операции дублируются в обеих последовательностях. За однократное выполнение этих операций отвечает Windows Installer. Это значит, что если операция выполнилась в последовательности InstallUISequence, в текущей последовательности она выполняться уже не будет. Это справедливо только для стандартных операций, за порядок выполнения пользовательских операций отвечает автор пакета инсталляции.

Выполнение последовательности InstallExecuteSequence

В таблице ниже приведена последовательность, которую я возьму в качестве примера для «разбора полетов». Сразу замечу, что операции уже упоминавшиеся выше я рассматривать не буду.

Action (Операция) Condition (Условие) Sequence(Последовательность)
AppSearch 400
LaunchConditions 410
FindRelatedProducts 420
CCPSearch CCP_TEST 500
RMCCPSearch Not CCP_SUCCESS And CCP_TEST 600
ValidateProductID 700
CostInitialize 800
FileCost 900
CostFinalize 1000
MigrateFeatureStates 1200
InstallValidate 1400
InstallInitialize 1500
ProcessComponents 1600
UnpublishComponents 1700
UnpublishFeatures 1750
StopServices VersionNT 1900
DeleteServices VersionNT 2000
SelfUnregModules 2200
UnregisterTypeLibraries 2300
UnregisterFonts 2500
UnregsiterExtensionInfo 2800
UnregisterProgIdInfo 2900
RemoveShortcuts 3200
RemoveFiles 3500
RemoveFolders 3600
CreateFolders 3700
InstallFiles 4000
PatchFiles 4090
CreateShortcuts 4500
RegisterExtensionInfo 4700
RegisterProgIdInfo 4800
RegisterFonts 5300
RegisterTypeLibraries 5500
InstallServices VersionNT 5800
StartServices VersionNT 5900
SelfRegModules 5905
RegisterUser 6000
RegisterProduct 6100
PublishComponents 6200
PublishFeatures 6300
PublishProduct 6400
InstallExecute 6411
RemoveExistingProducts 6599
InstallFinalize 6600
Таблица 15.

Как видим, эта последовательность операций намного длиннее, чем последовательность пользовательского интерфейса. Это и неудивительно, ведь здесь и производится практически вся работа по установке приложения в системе.

ПРИМЕЧАНИЕ

Я позволил себе не рассматривать довольно большую часть операций, и объединить некоторые из них в группы. Иначе я рисковал не закончить эту статью никогда – настолько обширен список.

Кстати, если в вашем инсталляционном пакете не нужны функции типа установки драйверов ODBC, шрифтов, служб WindowsNT – можете смело удалить соответствующие операции из последовательностей. Только учтите, что обычно эти операции идут парами.

Операция AppSearch

Операции с AppSearch по CostFinalize уже рассматривались выше. Идем дальше.

Операция InstallValidate

Эта операция выполняет две важных задачи:

1. Проверяет наличие места на тех дисках, которые были выбраны для установки при выполнении операций CostInitialize – CostFinalize. Если места на каком-либо из дисков не хватает, процесс инсталляции прерывается.

Обычно такие же действия выполняются ранее в последовательности пользовательского интерфейса. При этом в инсталляционном пакете должен существовать диалог с именем OutOfSpace, в котором показывается список дисков, на которых недостаточно места. Этот диалог помогает пользователю сориентироваться в ситуации и решить, что делать дальше: сменить место установки, очистить нужные диски, установить меньшее количество компонентов или вовсе отказаться от установки. В случае «тихой установки» операция InstallValidate просто прекращает процесс и делает соответствующую запись в журнальный файл (если журналирование разрешено).

2. Проверяет возможность переписывания или удаления файлов. Если какой-либо из файлов занят активным процессом – ядро Windows Installer информирует об этом пользователя.

При выполнении операций оценки места на дисках во внутреннюю таблицу FilesInUse добавляются записи для всех таких файлов. Эта таблица содержит имена файлов и полные пути к ним. Далее, при выполнении операции InstallValidate, ядро Windows Installer обрабатывает эти записи и определяет имена открывших файлы процессов. Информация об этих именах заносится в таблицу ListBox. Данные в этой таблице имеют следующий вид:

Property Value Text
FileInUseProcess Имя процесса Текст заголовка главного окна процесса
Таблица 16.

Все записи, имеющие одинаковое имя в столбце Property, будут показываться в одном окне ListBox. В нашем случае Windows Installer будет добавлять в таблицу записи с именем FileInUseProcess.

Затем показывается диалоговое окно FilesInUse. В этом окне показываются все запущенные процессы в системе, мешающие продолжению процесса установки. Окно также предоставляет пользователю возможность продолжить или прекратить установку продукта.

Операция InstallInitialize

Эта операция помечает начало процесса изменения состояния системы, иными словами, начинает транзакцию. Соответственно, окончание помечается операцией InstallFinalize (последней операцией в последовательности). Все операции, так или иначе влияющие на систему (такие, как InstallFiles или WriteRegistryValues) должны находиться между этими двумя операциями.

Транзакция в данном случае означает следующее: все изменения в системе на самом деле не производятся, а создается скрипт, в который записываются все необходимые операции по изменению реестра, копированию, удалению, изменению файлов и так далее. Выполняться этот скрипт будет в операции InstallFinalize. Таким образом, инсталляцию до операции InstallFinalize очень легко и просто отменить. Впрочем, обо всем по порядку.

Операция ProcessComponents

Эта операция используется для регистрации и дерегистрации компонентов устанавливаемого ПО.

Операции PublishComponents и UnpublishComponents

Эти операции манипулируют записью в реестр информации о компонентах для деинсталлируемых опций программы. При этом используется таблица PublishComponent. В данном случае публикация не имеет ничего общего с инсталляцией по требованию. В документации Microsoft признается, что название таблицы и ее полей выбраны весьма неудачно, так как операции и таблица используются для работы с так называемыми квалифицированными компонентами (в оригинале – qualified components). Эта тема выходит за рамки данной статьи, так что вдаваться в подробности я не буду. Скажу только, что в качестве одного из примеров таких компонентов можно взять динамически компонуемые библиотеки с ресурсами для разных языков, имеющие одно и то же имя.

Операция UnpublishFeatures

Эта операция выполняется при полной деинсталляции программного продукта. При этом из реестра удаляется вся информация об опциях и компонентах данной программы. Операция обрабатывает информацию из таблицы FeatureComponents.

Операция StartServices, StopServices, InstallServices и DeleteServices

Эти операции используются только в семействе Windows NT и служат для управления установкой и удалением служб. Они работают с таблицами ServiceControl и ServiceInstall.

Операции SelfRegModules и SelfUnregModules

Эти операции используются для удаления и установки саморегистрирующихся модулей (то есть динамических библиотек, экспортирующих функции DllRegisterServer и DllUnregisterServer). При выполнении этих операций используется таблица SelfReg. На всякий случай напоминаю, что использование саморегистрации в процессе инсталляции не поощряется (почему – смотри первую часть цикла).

Операциия RegisterTypeLibraries и UnregisterTypeLibraries Эти операции используются для регистрации (и отмены регистрации) библиотек типов. В своей работе используют данные из таблиц TypeLib, Component, Directory и Feature.

Операции RegisterFonts и UnregisterFonts

Эти операции используются для регистрации шрифтов. При этом используются таблицы Font и Component.

Операции RegisterExtensionInfo и UnregisterExtensionInfo

Эти операции выполняют регистрацию/дерегистрацию серверов расширений имен файлов. При этом используются таблицы Extension, Component, Feature, ProgId и MIME. Последняя используется редко.

Примеры таблиц приведены ниже:

Extension Component_ ProgId Feature_
lnl Constructor.exe Constructor.Document LineEditor
gdb Vega.exe Vega.Application Core
wml Be.exe BlockEditor.Document BlockEditor
Таблица 17. Таблица Extension.
ProgId Class Description
Constructor.Document {4CA1938F-DD64-44AE-82E1-FBB9F0C21B82} Редактор линий
Vega.Application {F55AD342-DAE2-11D2-B91E-0080AD190F7E} Приложение ‘Вега’
BlockEditor.Document {01DF6256-D867-44B1-A2DB-47136777CEC4} Редактор блоков
Таблица 18. Таблица ProgID.
Component ComponentId
Constructor.exe {301E0EE9-D510-4840-AF1F-7765EA70C741}
Vega.exe {4C86D98A-6FDA-4A47-B455-A1CEFC4114B3}
Be.exe {41BB06E4-9B50-44F4-8280-67E279F300F9}
Таблица 19. Таблица Component.
Feature Title
LineEditor Редактор линий для ГИС ‘Вега’
Core ГИС ‘Вега’ 2.1
BlockEditor Редактор знаков для ГИС ‘Вега’
Таблица 20. Таблица Feature.

Операции RegisterProgIdInfo и UnregisterProgIdInfo

Эти операции используются для регистрации информации о программных идентификаторах OLE, используемых в программе. При этом используются данные из таблиц ProgID, Component, Class и Extension. Пример таблицы Class приведен ниже:

CLSID Context Component_ ProgId_Default Description
{F55AD342-DAE2-11D2-B91E-0080AD190F7E} LocalServer Vega.exe Vega.Application Приложение ‘Вега’
Таблица 21.

Операции CreateShortcuts и RemoveShortcuts

Эта пара операций используется для управления ярлыками. При этом операция RemoveShortcuts удаляет публикуемый ярлык, если удаляется связанная с ним опция программного продукта и непубликуемый ярлык, если удаляется связанный с ним компонент. Соответственно, операция CreateShortcuts создает такие ярлыки. Эти операции обращаются к таблицам Shortcut, Directory, Component, Feature и Icon.

Операция RemoveFiles

Эта операция используется для удаления файлов, ранее установленных при выполнении операции InstallFiles.

Кроме того, эта операция может удалять и другие файлы. Эти файлы перечисляются в таблице RemoveFile.

Операции CreateFolders и RemoveFolders

Как можно догадаться из названия, эти операции используется для удаления и создания каталогов. Каталоги создаются для тех компонентов, которые должны быть установлены локально. При этом обрабатываются таблицы CreateFolder, Directory и Component. Каждый вновь созданный каталог связывается с соответствующим идентификатором компонента (полем ComponentId таблицы Component). Соответственно, при удалении таких компонентов удаляются и связанные каталоги. Учтите, что Windows Installer может удалять только пустые каталоги, поэтому операция RemoveFolders должна выполняться после операции RemoveFiles.

Операция InstallFiles

Это одна из самых важных операций. При ее выполнении происходит копирование файлов, перечисленных в таблице File на жесткий диск целевого компьютера. При этом, само собой, копируются только те файлы, которые должны быть установлены локально. Для определения таких файлов Windows Installer анализирует состояние компонентов из таблицы Component.

Операция PatchFiles

Эта операция используется для наложения «заплат» на файлы, то есть записи мелких изменений. При этом заменяются не файлы полностью, а только отдельные их части с точностью до байта. При выполнении операции используются данные из таблицы Patch.

Операция RegisterUser

Эта операция регистрирует информацию о пользователе продукта в системе.

Операция RegisterProduct

Эта операция регистрирует информацию о продукте в системе. При этом в реестр прописывается информация, использующаяся затем при выполнении системной команды Установка и удаление программ. Кроме того, Windows Installer кэширует инсталляционную базу на жестком диске, в каталоге %SystemRoot%\Installer.

Этот каталог имеет атрибуты Скрытый и Системный, поэтому при настройках Windows Explorer по умолчанию Вы его не увидите. При кэшировании сохраняется практически полная копия пакета инсталляции, за исключением, пожалуй, только неупакованных в .msi-пакет файлов. Размеры кэша могут быть весьма немалыми, например, на моей рабочей машине файлы в этом каталоге занимают около 200 мегабайт.

Операция использует два свойства: ARPNOMODIFY и ARPNOREMOVE. Если задано первое свойство, то при выполнении команды Установка и удаление программ пользователь не сможет изменить набор опций установленной программы, если задано второе свойство, то пользователь не сможет удалить программу с помощью этой команды.

Операция PublishFeatures

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

При выполнении операции используются три уже хорошо знакомых там таблицы: FeatureComponents, Feature и Component.

Операция PublishProduct

Данная операция используется для публикации сведений о программном продукте в системе в случае инсталляции по требованию. Честно говоря, я не знаю, почему эта операция существует в последовательности инсталляции. Вроде бы, по смыслу, ей положено быть только в последовательности публикации. В MSDN на эту тему сказано очень мало, к тому же еще и с ошибками. Дословно там сказано следующее:

          This action publishes the product if the product is in advertise mode or if the MsiGetProductInfo function returns ERROR_INSTALL_PRODUCT for the product.

        

Причем, кода ошибки ERROR_INSTALL_PRODUCT Вы не найдете нигде, так что трудно понять, когда же еще вызывается эта операция.

Операция InstallExecute

Эта операция запускает на выполнение скрипт, содержащий команды по изменению состояния системы, который был сгенерирован при выполнении предыдущих операций. В отличие от операции InstallFinalize, данная операция не завершает транзакцию по изменению состояния системы. Следовательно, при необходимости предыдущее состояние системы может быть восстановлено после отката транзакции.

Операция RemoveExistingProducts

Эта операция служит для удаления программных продуктов, сведения о которых содержатся в таблице Upgrade. Выполняется операция только один раз – при первой установке программы.

При выполнении операции Windows Installer проходит по всем записям таблицы Upgrade и удаляет все перечисленные в ней программы путем запуска вложенных процессов инсталляции (в данном случае правильней было бы сказать – вложенных процессов деинсталляции). В каждом таком процессе Windows Installer присваивает свойству ProductCode значение кода продукта из поля ActionProperty, а свойству REMOVE - значение поля Remove таблицы Upgrade. Если это поле пусто, то свойство REMOVE принимает значение ALL и удаляется весь программный продукт, в противном случае в этом поле должен содержаться список тех опций существующей программы, которые необходимо удалить при установке нового ПО.

Напомню, что в поле ActionProperty содержится имя свойства, которое, в свою очередь, хранит список кодов продуктов, разделяющих одинаковый код обновления (смотрите операцию FindRelatedProducts). Таким образом, одна строка, в таблице Upgrade, может запустить несколько операций удаления существующих программных продуктов.

При запуске этой операции Windows Installer определяет свойство UPGRADINGPRODUCTCODE, это позволяет разработчику инсталляционного пакета различать контекст, в котором происходит удаление продукта и предпринимать соответствующие действия. То есть, если это свойство не определено, удаление приложения было инициировано пользователем, например, через выполнение команды Установка и удаление программ, в противном случае – удаление было инициировано другим инсталляционным пакетом.

Операция InstallFinalize

Эта операция помечает окончание процесса изменения состояния системы. При этом запускается сгенерированный при выполнении предыдущих операций скрипт, который содержит команды по изменению состояния системы. Эта операция заканчивает транзакцию, начатую операцией InstallInitialize.

Если эта операция выполняется в процессе полной деинсталляции программы, выполняются следующие действия: в скрипт автоматически добавляются инструкции по удалению информации для команды Установка и удаление программ, дерегистрации и депубликации продукта, а также по удалению локальной базы из каталога %SystemRoot%\Installer.

После выполнения этой операции уже невозможно стопроцентно точно восстановить прежнее состояние системы.

Итак, мы добрались до успешного окончания процесса инсталляции программы. Теперь можно получать удовольствие (или головную боль – это уж кому как повезет) от установленного продукта.

Откат

Но не всегда все проходит гладко: может произойти сбой в программе установки, в операционной системе, да мало ли еще что. И здесь приходит на помощь откат, помогающий восстановить первоначальное состояние системы.

Как же работает механизм отката? При генерации инсталляционного скрипта (того самого, что выполняется в операции InstallFinalize) Windows Installer одновременно генерирует скрипт для отката и сохраняет информацию о файлах, каталогах и ветвях реестра, изменяемых при установке. Эта информация сохраняется в специальном скрытом каталоге, создаваемом на время установки в корне системного диска. На моей машине этот каталог имеет имя C:\CONFIG.MSI. Подчеркиваю, что каталог временный и создается только на время установки. После нормального окончания процесса инсталляции все файлы из этого каталога удаляются, затем удаляется и сам каталог. Но если что-то пошло не так, Windows Installer автоматически выполняет откат.

Автоматический откат – это поведение Windows Installer по умолчанию. Это поведение можно изменить, задав соответствующие значения свойствам DISABLEROLLBACK и PROMPTROLLBACKCOST или выполнив операции DisableRollback. Также у Windows Installer есть управляющее событие EnableRollback, позволяющее включать или выключать возможность отката в зависимости от некоторых условий, например, свободного места на диске.

Итак, рассмотрим, что же за информация сохраняется в каталоге CONFIG.MSI.

Если мы посмотрим на содержимое каталога, то увидим прежде всего один файл с расширением .rbs, и кучу файлов с расширением .rbf. Имена всех этих файлов состоят из буквенно-цифровой абракадабры и для нас не важны. А вот то, что файл .rbs только один, заставляет задуматься о многом. И действительно, если просмотреть его, можно обнаружить, что этот файл играет важную роль в выполнении отката. Он содержит весьма интересную информацию, а именно:

1. Информация об устанавливаемом программном продукте. Здесь содержится информация обо всех опциях и компонентах программы, так или иначе затрагиваемых активным инсталляционным процессом.

2. Информация о модифицируемых, добавляемых или удаляемых записях реестра.

3. Информация о файлах. Эта информация делится в свою очередь на две группы:

4. Исполняемые файлы формата .PE. Почему часть файлов попала сюда, а не в соответствующий rbf-файл, я не знаю. Но, тем не менее, они здесь есть.

5. Другая информация, которая наверняка здесь есть, но о присутствии и назначении которой я не догадался.

ПРИМЕЧАНИЕ

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

Заключение

Как видим, процесс инсталлирования даже простого программного продукта на компьютер – операция довольно сложная. И я скромно надеюсь, что выполнил свою задачу, и после прочтения статьи у вас появилось более ясное понимание того, как происходит процесс инсталляции. Хотя, честно говоря, мне самому далеко не все понятно. Но не беда, на форумах сайта www.rsdn.ru можно найти ответы практически на все вопросы по компьютерной тематике, в том числе и по инсталляции программных продуктов. Так что если у вас есть вопросы – заходите в форумы и спрашивайте, вам обязательно помогут или хотя бы попытаются помочь, что тоже немало и часто помогает самостоятельно найти путь к верному решению.

Я не буду обещать скорого появления новой статьи (особенно учитывая, сколько прошло времени между первыми двумя статьями), могу только сказать, что планы продолжить тему Windows Installer есть, но с конкретной темой я еще не определился: поле для деятельности здесь просто огромное. Если кто-то имеет что сказать на эту тему – присоединяйтесь.

Хочу выразить огромную благодарность Колечкину Михаилу за помощь в подготовке статьи.

Источники информации


Эта статья опубликована в журнале RSDN Magazine #1-2004. Информацию о журнале можно найти здесь
    Сообщений 0    Оценка 235 [+1/-0]         Оценить