Админ

воскресенье, 15 сентября 2013 г.

Менеджер обновлений программ Windows своими руками

|
Попалась мне тут на днях на Хабре вот такая статья: Репозитории для Windows, или как устанавливать программы быстрее. Разговор в ней идёт о пакетных менеджерах для быстрой установки программ в ОС Windows. В этой связи я вспомнил о том, как пару лет тому назад делал похожий менеджер для нашей организации.

Предыстория

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

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

К 2009 году проблему стало невозможно игнорировать, и я начал изучать существовавшие программы для автоматического апгрейда приложений. Как выяснилось, большинство из них рассчитаны на обновление отдельных приложений, а у нас их несколько десятков, причём между некоторыми из них существуют зависимости. Наиболее подходящей была бы схема, похожая на менеджеры пакетов в дистрибутивах Linux, но ничего похожего я тогда не нашёл и сам взялся за разработку.

Я решил начать с простого — с программы для установки и обновления отдельного приложения, которая впоследствии могла бы развиться в то, что нужно. Основная работа была проделана за несколько свободных вечеров. Самым сложным было придумать название для программы. Помучившись, я махнул рукой и назвал программу первым же словом, которое пришло в голову. Это оказалось слово

WhiteCrow. Обновление приложений


Программа должна была удовлетворять следующим требованиям:
  1. Отсутствие необходимости вносить какие бы то ни было изменения в код обновляемого приложения. Приложение вообще не должно «знать» ничего об обновлениях (чтобы не переписывать код, тем более, что новый код наверняка в итоге будет дублироваться во всех приложениях).
  2. Простота поддержки актуальности версий обновляемого приложения.
  3. Небольшой размер, насколько это возможно, — как самой программы, так и по объёму передаваемых через сеть данных.
И вот, что из этого вышло:
  1. Программа WhiteCrow должна проверять обновления при каждой попытке пользователя запустить обновляемое приложение. Самый простой способ это сделать — изменить свойства ярлыка для запуска этого приложения. Ярлык ссылается на исполнимый файл WhiteCrow.exe и передаёт первым параметром путь к локальному файлу, который содержит различные данные, в том числе адрес в сети файла со сведениями об обновлении (см. п. 2). Остальные параметры — это командная строка для запуска приложения, заголовок и ещё кое-какие служебные сведения. WhiteCrow запускается и проверяет номер версии: если версия на сервере новее, чем на компьютере пользователя, то пользователь получает сообщение с предложением скачать эту версию. Если он согласится, то приложение будет скачано, переустановлено и запущено. Если же обновлений не было, приложение будет просто запущено безо всяких сообщений и без открытия дополнительных окон. Информация о версии приложения на компьютере пользователя может извлекаться из ветки реестра (обычно используется та же ветка, которую проверяет апплет «Установка и удаление программ» из Панели управления Windows), из ini-файла или непосредственно из exe-файла приложения (если там включена информация о версии).
  2. Я остановился на простой идее: номер версии приложения и некоторая другая информация писались в небольшой — десятки байт — текстовый файл, который скачивается с сервера при каждом запуске программы. Файл крошечный, поэтому загружается он быстро. Он не содержит никакой информации, кроме названия программы, номера версии и пары путей: к exe-файлу для установки и к страничке в формате HTML с описанием изменений в новой версии — этот текст будет показан пользователю в сообщении о новой версии (см. скриншот).
  3. Сама программа занимает что-то около 360 Кб, а данные, которые она передаёт через Интернет при подключении, вовсе измеряются сотнями байтов, если нет обновлений (если есть, то всё зависит от размеров обновляемого приложения).
Программа была благополучно установлена летом 2010 года на все клиентские машины в приёмной комиссии (поскольку проблема там стояла острее всего), и работает там до сих пор. Поскольку свою основную функцию для данного конкретного случая она выполняет, я не стал заменять её на новую версию, о которой ниже. Сам же, вдохновлённый первым успехом, взялся за реализацию второго этапа: создание полноценного менеджера обновлений для наших приложений. Не мудрствуя лукаво, программа была названа

WhiteCrow 2. Менеджер установки и обновления программ для Windows



Программа была готова осенью 2010. Источником вдохновения при создании этой программы, как я уже упоминал, послужили менеджеры пакетов Linux и отчасти магазины приложений, которые не так давно обрели популярность с распространением мобильных ОС. 

К изложенным ранее требованиям добавились новые:
  1. Поддержка наборов приложений, разбитых на категории, а не просто одного приложения. 
  2. Поддержка зависимостей между приложениями.
По последнему пункту можно сказать особо: ещё в 2005 году мне поручили разработать подсистему генерации отчётности, которая бы позволила разделить программы для ввода данных и модули генерации отчётов. Поясню на примере: есть приложение A, которое может генерировать отчёт X по данным из БД, и есть приложение B, которое должно уметь генерировать тот же отчёт X. Начальство решило, что переписывать один и тот же код генерации отчётов из программы в программу неэффективно, и мне предложили «придумать что­-нибудь». В итоге получилась система DLL­-библиотек, которые реализуют наборы отчётов и подключаются к программам на манер плагинов, то есть программы могут работать и без них, при этом просто не смогут генерировать некоторые отчёты. Система оказалась достаточно удачной, чтобы использоваться до сих пор, но у неё был минус: либо программа установки каждого приложения должна была включать самые свежие DLL, либо пользователю было нужно было скачивать программу для установки DLL с сайта отдельно. Так как новые версии программ выходили с разной частотой, иногда возникали коллизии, когда более старое приложение устанавливалось на тот же компьютер позднее более нового приложения, и более свежие DLL заменялись более старыми (это общеизвестная для Windows проблема, которая часто называется «DLL hell»). Если бы удалось реализовать зависимости между «пакетами» (используя терминологию Linux), то можно было бы просто выделить каждую DLL в отдельный «пакет» и обновлять их по отдельности, не заботясь о том, что более старая библиотека может затереть более новую.

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

Программа WhiteCrow 2 может запускаться двумя разными способами. Первый способ — запуск в режиме «менеджера пакетов» (как показано на рисунке). При этом запускается основной файл программы — WhiteCrow2.exe — с единственным параметром, представляющим собой адрес XML­-файла. Программа показывает содержимое этого XML­-файла (и всех связанных с ним) в виде списка категорий и «пакетов» внутри них. Каждый «пакет» отмечен иконкой, показывающей его статус (например, «стоит самая свежая версия», «не установлен», «обновление», «критическое обновление»), можно выбрать пакет из списка и посмотреть подробности: описание, список зависимостей и прочее. Можно, наконец, удалить установленное ненужное приложение. 

Во втором режиме программа используется для обновления единственного приложения (как и первая версия WhiteCrow). Здесь по­-прежнему используется подмена ярлыков. Ярлык ссылается на файл WhiteCrow2.exe и содержит уже два дополнительных параметра: адрес XML­-файла и имя «пакета» внутри этого файла. Основное отличие от первой версии заключается в том, что WhiteCrow 2 умеет проверять версию не только самого приложения или DLL, но всех его зависимостей, в том числе по цепочке (когда «пакет» A зависит от B, а тот зависит от C, то при запуске проверяются обновления для всех трёх). Кроме того, программа WhiteCrow 2 умеет проверять собственные обновления (причём не с некоторого фиксированного сервера нашей организации, который сегодня есть, а завтра нет, а с адреса, указанного в XML, который подчиняется тем же требованиям и условиям, что и все прочие).

Программа стала устанавливаться на компьютеры пользователей в начале 2011 года и сэкономила нам уже немало времени и нервов. Теоретически эту программу можно использовать не только для установки и обновления своих собственных приложений, но и для установки и обновления любых других нужных программ (правда, при этом придётся подумать о ярлыках для обновления). Установочные файлы приложений ведь не нужно хранить на своём сервере, достаточно написать адрес в XML­-файле.

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

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

Во-вторых, нужен кто-то, кто возьмёт на себя роль maintainer’а (опять-­таки в терминах Linux), то есть будет вводить в XML информацию о номерах свежих версий приложений. Хотя эту работу тоже можно было бы частично перепоручить скрипту, который мог бы, например, регулярно мониторить содержимое каталога на сервере в поисках свежих файлов.

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

В-четвёртых, программа на данный момент использует протокол HTTP для обмена данными с сервером. Нет никакой принципиальной сложности перевести её, скажем, на FTP, просто у нас в этом пока не было необходимости.

В-пятых (хотя это и не совсем вина моей программы), хотя я и старался сделать программу, скажем так, UAC-­friendly (то есть совместимой с системой разрешений, введённой в Windows Vista и доработанной в последующих версиях — для меня это вообще давно уже стало нормой), это не совсем удалось. Программы установки некоторых приложений требуют прав администратора, так что при обновлении такого приложения пользователь может получить запрос на ввод пароля администратора. Но, повторяю, это связано не с самим менеджером обновлений, а с конкретными приложениями.

На сегодняшний день число конфигураций приложений с отдельными установочными версиями (включающими exe-файл, разные вспомогательные файлы, настройки и прочее) составляет порядка 70, а количество «видов» пользователей, для которых создаются отдельные наборы XML-файлов, превышает 35.

Итак, направления усовершенствования есть, хотя в последнее время меня стала занимать другая идея, вылившаяся в программу с незамысловатым названием

WhiteCrow 3. Виртуальные рабочие столы


Наблюдение за пользователями, которые запускали наши приложения, подтолкнуло к одному выводу. Дело в том, что в режиме списка программу WhiteCrow 2 можно использовать не только для обновления приложений, но и для их запуска (так было сделано изначально). Так почему бы не сделать это штатным режимом работы для пользователей, чтобы им не приходилось искать приложение в меню кнопки «Пуск» или на традиционно захламлённом иконками Рабочем столе Windows? И тогда я попробовал сделать собственный launcher для наших приложений. Теперь уже источником вдохновения послужили не только репозитории Linux, но и широко известная система цифровой дистрибуции Steam фирмы Valve, которая как раз объединяет оболочку для запуска программ с менеджером обновлений.

Система пока не завершена (времени, увы, было мало). В ней предполагается сделать некое рабочее пространство — виртуальный «рабочий стол». На этом «столе», как и на обычном рабочем столе Windows, есть иконки, точнее, «кнопки» приложений, которые этот пользователь может запускать щелчком (набор доступных «кнопок» определяется учётной записью пользователя). Каждая такая «кнопка» может не только запускать приложение, но и выполнить какие-то дополнительные действия, например, открыть файл с описанием программы или запустить связанное приложение (см. на рисунке кнопку «Расписание занятий» с двумя дополнительными подпунктами к ней).

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

Запускаемое таким образом приложение вовсе не обязано быть установленным в системе (скорее всего, уже установленные приложения будут иметь другую иконку, чтобы совсем уж не запутывать пользователя). При запуске программа проверяет (1) установлено ли приложение и (2) если да, то свежая ли версия. Если ответ «нет» на любой вопрос, то должна происходить автоматическая и более или менее прозрачная для пользователя (насколько позволяет пропускная способность сети и быстродействие компьютера) установка / обновление приложения.

Скорее всего, программа будет использовать XML той же структуры, что и WhiteCrow 2 (поскольку уже накоплен большой объём этих файлов и у других разработчиков в нашей организации есть опыт работы с ними, да и вообще: зачем выбрасывать удачное решение на помойку?).

Кое-­какая функциональность у программы уже имеется: она уже умеет отображать виртуальные «рабочие столы» и показывать пользователю новости с сайта из потока RSS (это видно на картинке справа). Я пока не знаю, доделаю я это всё когда­-нибудь или оно так и останется в виде набросков и идей, хотя начальство проявляет некоторую заинтересованность (с комментарием «но только в свободное от основной работы время!», так что у меня это держится на таком же чистом энтузиазме, как и предыдущие проекты). Повальный переход на web­-приложения в обозримом будущем нашей организации пока не грозит, поэтому шансы есть.

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

Комментариев нет:

Отправить комментарий

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

К началу