Поделиться через


Установка по запросу для игр

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

Обзор

Установка была элементом компьютерных приложений в течение длительного времени. Большинство приложений сегодня требуют, чтобы они были установлены на локальном жестком диске пользователя, прежде чем их можно будет использовать. Компьютерные игры не являются исключением; когда потребитель покупает игру Microsoft Windows и пытается запустить ее, он должен сначала пройти процесс установки, который копирует необходимые файлы с диска игры на жесткий диск. Этот процесс установки обычно длинен и может занять столько часа, сколько час. Время установки является фактором, который делает консольные игры более желательными, чем компьютерные игры для некоторых игроков, так как они могут немедленно играть в консольную игру после вставки диска игры. Технология, описанная в этой статье, попытается устранить это путем резкого сокращения времени установки.

Традиционно игры требуют установки всех или большинства файлов перед запуском. Чтобы обеспечить установку по запросу, игровые ресурсы должны быть модульными; То есть разработчик должен разделить ресурсы приложения (графику, звук и т. д.) на компоненты. Каждый компонент — это набор ресурсов, которые можно установить или удалить как единицу. После этого разработчик игры определяет одну или несколько функций, как правило, один или несколько на уровне или зоне. Каждая функция приложения задает набор компонентов, необходимых для выполнения конкретной функции. При установке приложения его компоненты можно пометить как "установить" (компоненты, скопированные на локальный жесткий диск во время установки) или "объявленные" (компоненты, скопированные на локальный жесткий диск после первоначальной установки, когда приложение использует эту функцию). Разработчик игры может сократить время установки, создав игру для запуска и запуска с минимальным набором установленных компонентов. Остальные его функции можно пометить как объявленные и установленные по запросу, когда приложение фактически должно использовать функциональные возможности, предоставляемые этими функциями.

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

Поддержка исправлений

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

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

Пример пакета SDK InstallOnDemand

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

Запуск примера

  1. Используйте ссылку "Установить проект" в примере браузера, чтобы скопировать файлы примера в папку.
  2. Дважды щелкните InstallOnDemand.msi, чтобы установить пример.
  3. Выберите типичную установку.
  4. Запустите пример, запустите файл InstallOnDemand.exe в установленной папке (обычно Program Files\InstallOnDemand) или запустите из меню "Пуск"\Программы.

InstallOnDemand.msi — это база данных, распознаемая установщиком. Он определяет весь процесс установки: структуру каталогов, что и не будет копироваться, какие ресурсы будут копироваться вместе, какие значения реестра следует записывать, какие сочетания клавиш для создания и т. д.

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

В правой части примера экрана пять кнопок, помеченных как "Уровень воспроизведения 1" и "Уровень воспроизведения 5". Эти кнопки имитируют завершение игрока текущего уровня и переход к следующему. После нажатия одной из этих кнопок появится экран статистики, показывающий сведения о уровне, который он только что закончил. Пример также занимает это время, чтобы попросить установщика проверка и установить следующий уровень, если он еще не установлен. Установка происходит, когда проигрыватель считывает экран статистики, поэтому когда пользователь нажимает кнопку "ОК", чтобы ввести следующий уровень, ресурсы уровня устанавливаются и готовы к загрузке.

Компоненты и компоненты примера

Традиционно игры требуют установки всех или большинства файлов перед запуском. Чтобы обеспечить установку по запросу, игровые ресурсы должны быть модульными; То есть разработчик должен разделить ресурсы приложения (графику, звук и т. д.) на компоненты. Каждый компонент — это набор ресурсов, которые можно установить или удалить как единицу. После этого разработчик игры определяет одну или несколько функций, как правило, один или несколько на уровне или зоне. Каждая функция приложения задает набор компонентов, необходимых для выполнения конкретной функции. При установке приложения его функции можно пометить как "установить" (компоненты, скопированные на локальный жесткий диск во время установки) или "объявленные" (компоненты, скопированные на локальный жесткий диск, когда приложение позже использует эту функцию). Разработчик игры может сократить время установки, создав игру для запуска и запуска с минимальным набором установленных компонентов. Остальные его функции можно пометить как объявленные и установленные по запросу, когда приложению на самом деле нужно использовать функциональные возможности, предоставляемые этими функциями.

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

Имя функции Функция Компоненты Files
Основные сведения Включает ресурсы, необходимые всегда независимо от уровня. Эти ресурсы: пример исполняемого файла, носитель, необходимый для внедрения последовательности и загрузки экрана, и FX-файл, который обрабатывает все отрисовки в примере. Основные сведения InstallOnDemand.exe, InstallOnDemand.fx, Loading.bmp, Level.x
Основные сведения (то же, что и выше) CoreUI Media\UI\dxutcontrols.dds, Media\UI\DXUTShared.fx, Media\UI\arrow.x
Основные сведения (то же, что и выше) CoreMisc Media\Misc\seafloor.x, Media\Misc\seafloor.bmp
Основные сведения (то же, что и выше) CoreSpeeder Media\PRT Demo\LandShark.x, Media\PRT Demo\speeder_diff.jpg
Основные сведения (то же, что и выше) CoreReg N/A (значение реестра)
Level1 Предоставляет ресурсы, используемые уровнем 1. Level1 Level1.jpg
Level1 (аналогично предыдущему) L1Skybox Media\Light Probes\galileo_cross.dds
Level2 Предоставляет ресурсы, используемые уровнем 2. Level2 Level2.jpg
Level2 (аналогично предыдущему) L2Skybox Media\Light Probes\grace_cross.dds
Level3 Предоставляет ресурсы, используемые уровнем 3. Level3 Level3.jpg
Level3 (аналогично предыдущему) L3Skybox Media\Light Probes\rnl_cross.dds
Level4 Предоставляет ресурсы, используемые на уровне 4. Level4 Level4.jpg
Level4 (аналогично предыдущему) L4Skybox Media\Light Probes\stpeters_cross.dds
Level5 Предоставляет ресурсы, используемые на уровне 5. Level5 Level5.jpg
Level5 (аналогично предыдущему) L5Skybox Media\Light Probes\uffizi_cross.dds

 

Функции Level1–Level5 содержат дополнительные вложенные функции, содержащие файлы, которые не используются непосредственно примером. Эти вложенные файлы были добавлены, чтобы установка занимает больше времени. Это делается для иллюстрации текущей операции установки, выполняемой в фоновом режиме во время выполнения примера.

В следующей таблице перечислены вложенные функции.

Компонент Вложенные функции Files
Level1 L1PH1, L1PH2, L1PH3, L1PH4, L1PH5 Данные заполнителя level1\L1PH1.dat Level1 Placeholder Data\L1PH2.dat Level1 Placeholder Data\L1PH3.dat Level1 Placeholder Data\L1PH4.dat Level1 Placeholder Data\L1PH5.dat
Level2 L2PH1, L2PH2, L2PH3, L2PH4, L2PH5 Данные заполнителя Level2\L2PH1.dat Level2 Placeholder Data\L2PH2.dat Level2 Placeholder Data\L2PH3.dat Level2 Placeholder Data\L2PH4.dat Level2 Placeholder Data\L2PH5.dat
Level3 L3PH1, L3PH2, L3PH3, L3PH4, L3PH5 Данные заполнителя Level3\L3PH1.dat Level3 Placeholder Data\L3PH2.dat Level3 Placeholder Data\L3PH3.dat Level3 Placeholder Data\L3PH4.dat Level3 Placeholder Data\L3PH5.dat
Level4 L4PH1, L4PH2, L4PH3, L4PH4, L4PH5 Данные заполнителя Level4\L4PH1.dat Level4 Placeholder Data\L4PH2.dat Level4 Placeholder Data\L4PH3.dat Level4 Placeholder Data\L4PH4.dat Level4 Placeholder Data\L4PH5.dat
Level5 L5PH1, L5PH2, L5PH3, L5PH4, L5PH5 Данные заполнителя level5\L5PH1.dat Level5 Level5 Placeholder Data\L5PH2.dat Level5 Level5 Placeholder Data\L5PH3.dat Level5 Placeholder Data\L5PH4.dat Level5 Placeholder Data\L5PH5.dat

 

Во время установки основная функция должна быть помечена как "install", а все остальные компоненты должны быть помечены как объявленные. Установив только одну функцию вместо шести, время, когда игрок должен ждать, пока игра не запустится, значительно сокращается.

Установка

Установщик Windows предоставляет механизм для приложения, запрашивающего установку объявленной функции. Однако механизм является синхронным вызовом интерфейса программирования приложений (API), что означает, что приложению придется ждать внутри вызова до завершения установки. Чтобы достичь фоновой установки, рабочий поток требуется, чтобы основной поток приложения был свободен для выполнения других важных задач, таких как отрисовка на экране, чтобы продолжить предоставление визуального отзыва проигрывателя.

В примере есть три состояния установки, которые происходят во время примера выполнения: активная установка, пассивное установка и установка без установки.

  • Активная установка — это запрос, инициируемый примером, когда он должен получить доступ к ресурсам или загрузить их, предоставляемые одним или несколькими функциями. Этот пример делает это, если он не может продолжаться до установки ресурса.
  • Пассивной установки инициируется, если образец не выполняет критически важные задачи, например, когда игрок находится в меню или просматривает сцену вырезания. В этом случае рабочий поток проверка, если какая-либо функция примера по-прежнему объявлена. Если он может найти его, он вызывает установщик для установки этой функции. Этот процесс повторяется до тех пор, пока не будет установлена каждая функция примера. По сути, пассивные установки используют дополнительные циклы процессора для выполнения установки в фоновом режиме, если он является наименее навязчивым для основного примера.
  • Установка не происходит, когда игрок активно участвует в игре; Это предотвращает удаление кадров, которое будет нарушать взаимодействие с пользователем.

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

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

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

Пример вызывает CMsiUtil::EnablePassiveInstall() для включения или отключения пассивной установки. EnablePassiveInstall(true) увеличивает число включений для пассивной установки, а EnablePassiveInstall(false) уменьшает его. Если число включения больше 0, класс обработает очередь пассивной установки. Пример позволяет пассивной установке, если одно из следующих значений имеет значение true:

  • Пользователь просматривает начальную последовательность введения.
  • Пользователь перемещается в примере меню.
  • Пользователь просматривает статистику в конце уровня.
  • Пример приложения теряет фокус и переходит к фоновому режиму.

Ниже перечислены методы CMsiUtil:

Метод Description
AbortAllRequests Приводит к прерыванию текущей установки и очистке активной очереди запросов на установку.
AbortCurrentRequest Приводит к прерыванию установки. Затем рабочий поток обрабатывает следующий запрос в очереди, если он существует.
EnablePassiveInstall Приращения или уменьшения пассивной установки включается число. В примере используется этот вызов для управления, когда пассивные установки могут и не могут произойти.
GetCurrentFeatureName Возвращает имя активно установленной функции.
GetFeatureProgres Возвращает текущую позицию галочки для установленной функции.
GetFeatureProgressMax Возвращает максимальное количество тиков хода выполнения для установленной функции.
GetLastError Используйте этот метод для получения возвращаемого кода из предыдущего запроса на установку.
GetPassiveProgres Возвращает позицию галочки индикатора хода выполнения для пассивной установки.
GetPassiveProgressMax Возвращает текущее положение галочки и максимальное количество тиков для пассивной установки. Вместе пример может использовать их для отображения общего хода пассивной установки.
GetProgress Возвращает положение галочки индикатора хода выполнения для активной установки набора компонентов. Используется при отрисовке примера индикатора выполнения установки. Так как установщик Windows предоставляет только сведения о ходе установки одной функции, метод делит индикатор хода выполнения между запрошенными функциями, чтобы пользователь по-прежнему видел всю установку как одну задачу.
GetProgressMax Возвращает максимальное число галок индикатора хода выполнения для установки активного набора компонентов. Используется при отрисовке примера индикатора выполнения установки.
Инициализация Инициализирует класс с глобальным уникальным идентификатором продукта (GUID). Этот метод также перечисляет все функции приложения, которое было объявлено, но еще не установлено, и помещает его в очередь пассивной установки для настройки пассивной установки.
IsInstallInProgresss Используйте этот метод, чтобы узнать, обрабатывается ли активная установка.
UseFeature Закрытый метод, вызываемый UseFeatureSet. Проверяет, установлен ли компонент. Если запрошенная функция установлена, метод возвращается. Если компонент еще не установлен (объявлен), метод очереди нового активного запроса на установку рабочего потока, а затем возвращается. Необязательный дескриптор событий, который будет сигнализировать при завершении запрошенной установки.
UseFeatureSet Вызывается примером, когда он должен получить доступ к функциям, предоставляемым определенной функцией или любой из ее вложенных функций. Метод перечисляет все функции примера и вызывает UseFeature() для вложенных функций указанной корневой функции. Пример может передаваться в дескриптор событий, который будет сигнализировать при установке всего набора компонентов. Так как все компоненты, установленные в качестве набора, дескриптор указывается для последней очереди компонентов с помощью UseFeature() вместо каждой функции, чтобы образец уведомлялся после установки всех запрошенных компонентов.
UseProduct Очередь активного запроса на установку рабочего потока для вызова установщика для выполнения полной установки продукта. Необязательный дескриптор событий, который будет сигнализировать при завершении запрошенной установки.

 

Ограничение

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

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

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

Пример устанавливается путем запуска InstallOnDemand.msi, так как предполагается, что установщик Windows присутствует на компьютере. Если установщик отсутствует, msi-файлы не распознаются и запускают их не будут работать. Чтобы устранить эту проблему, приложение должно использовать программу установки для выполнения задачи. Эта программа должна сначала проверка, чтобы узнать, присутствует ли установщик и если да, его версия. Если версия не соответствует требованиям приложения, программа установки должна установить установщик Windows, а затем запустить MSI-файл. Этот процесс называется начальной загрузкой. Приложения обычно называют начальной установкой программы Setup.exe. Пример не обрабатывает начальную загрузку. Однако полные сведения о начальной загрузке можно найти в установщике Windows.

Разработчики также должны обратить внимание на размер каждой функции в своих играх. При отмене установки установщик восстанавливает компьютер до установки. Это означает, что установка компонента полностью отменена, и не существует частичной установки компонентов. Для установки большой функции требуется больше времени, что повышает вероятность прерывания и отмены установки, или установка будет препятствовать главному приложению. Примером будет включение пассивной установки, когда пользователь открывает игровое меню в середине игры. Если функция устанавливается, и пользователь возвращается к игре, игра может выполнить одно из двух действий: это может позволить пассивной установке завершить или отменить пассивные установки. Большая функция будет плохо подходит для любой модели. Если игра позволит выполнить большую установку, установка может затруднить производительность отрисовки игры в течение длительного времени. И наоборот, если игра отменяет установку, пользователь должен оставаться в меню в течение длительного времени, прежде чем вернуться в игру. Разработчики должны найти сбалансированный размер функций, который лучше всего подходит для своих отдельных игр.