|
Статья: Обновление приложений в MS Visual
FoxPro Часть 1 |
В этой статье :
Для чего написана эта статья.
Введение.
Как в идеале надо обновлять приложения.
Как это работает.
.
|
Почему я решил написать статью - да просто
прочитал рекламный листок одной большой компании, как она внедрила
один крупный проект в гостиничном бизненсе и это автообновление
позволило сократить много инженеров поддержки, которые занимались
только Upgrade на новые версии старой системы... Хорошие деньги за
такую простую функцию программы!... Но в FoxPro такая возможность
уже существует много лет и мы ее не используем из-за собсвенной
лени. Причем самообновление даже через интернет позволит
профессионально напоминать нашим клиентам - что мы, хоть и не такие
большие как Microsoft, но заботимся о наших клиентах, думаем о них и
развиваем систему. Кроме того подобный подход упрощает разработку -
получил задание по e-mail, выполнил работу, опубликовал на своем или
клиента Web Server, а на утро его сотня - тысяча клиентов скачали
новое обновление. Круто! Уровень сервиса как и в системе за
1 миллион долларов.
Думаю, что я не открою секрет, что подобная
проблема стояла перед многими из нас, кто связан с практической
разработкой программного обеспечения. И не важно - работаешь ты в
крупной "программерской конторе" пишущей для крупных
заказчиков или разрабатываешь приложение для "под заказ" для
небольших клиентов с минимальными ресурсами. Каждый решал эту
проблему по-своему. Путей решения много. Автор этой статьи пытался
решить данную проблему несколькими методами. Но после нескольких
методов изыскания и поиска нашел очень интересное решение,
преложенное Rick Strahl и выложенное на сайте компании
West Wind Technologies в свободном
доступе. Изучив преложенный материал я понял, что
это именно то, что мне нужно и лучше уже просто написать
невозможно. Так что моя данная статья будет неким кратким вольным
переводом с английского с некоторым облегчением кода и
разработкой реального примера. Для тех же, кто
знаком с английским языком сразу отсылаю к оригиналу. Мной было
получено разрешение на все вышеописанные действия от Рика, за что я
ему выражаю признательность и благодарность за создание прекрасных
продуктов на основе и для FoxPro - особенно Web Connection который "затыкает" по
скорости и удобству создания Web приложений многие
известные аналоги. |
Обновление установленных и работающих
приложений не является для большинства нас как разработчиков
приоритетной задачей. Обновление программ, особенно находящихся в
разных местах является не простым заданием. Если Вы сталкивались в
своей практике с разработкой и установкой программ для
клиентов с тысячью и более пользователей и найдя крошечный, но
критически важный баг, Вы аероятнее всего знакомы с исчезающим
чувством пустоты в Вашем желудке в тщетных попытках найти всех этих
пользователей и известить, что в программе ощибка но Вы уже ее
исправили и можете предоставить им улучшенную версию.
Обновление программ связано с решением
многих вопросов. Прежде всего Вам необходимо разработать способ
передачи обновления пользователю. Кроме того надо придумать как
проверять наличие новых версий и как собственно устанавливать
обновления на клиентские машины. Очень редко обновление требует от
нас замену только одного выполняемого EXE модуля основной программы,
но очень часто это затрагивает дополнительные файлы и что наиболее
существенно - требуется вносить изменения в структуру данных баз на
стороне клиента.
В данной статье мы сфокусируем Ваше внимание
как на практике провести процесс проверки наличия новой версии и
собственно обновления приложения через Интернет (Интранет, далее для
простоты написания я буду упускать змечание на то, что вся
информация будет каксаться и внутренних компьютерных сетей) а так же
связанных с данной тематикой некоторых сопутствующих проблем. В
дальнейшем будет представлен класс, разработанный Rick Strahl
который берет на себя всю черновую работу по проверке обновлений
on-line, затем прием новой версии с Web Site используя протокол HTTP
и обновление любого количества файлов, входящих в приложение.
|
Перед тем как углубиться в детальное
изучение работы класса
wwCodeUpdate, давайте кратко рассмотрим процессы,
участвующие в обновлении данных через Интернет. Для наших
пользователей внутри наших приложений мы должны выполнить следующие
задачи процесса обновления:
- Проверить
наличие новой версии у источника обновления путем сравнения online
версии с текущей локальной версией на клиенте
- Принять файл
обновления на локальную машину через Интернет
- Обновить
запущенный EXE модуль а так-же остальные файлы из принятой новой
версии
- Перезапустить оригинальное
приложение
- Запустить
любые после обновления приложения операции, например, изменение
структуры таблиц данных и т.д.
На первый взгляд описанный процесс выглядит
простым, но за этой простотой скрывается довольно большой объем
работ и внешнее приложение, призванные осуществить задуманное нами.
Типичный сценарий работы программы обычно выглядит примерно так:
Приложение стартует и как часть процесса загрузки приложения
происходит проверка номера последней достуаной версии данной
программы через Web путем чтения XML файла, который содержит
номер последней версии и так-же дополнительной информации об
обновляемом файле (URL, размер файла обновления, сообщение Вашему
пользователю). Эта информация в части номера последней
версии сравнивается с текущим номером локальной версии,
используемой клиентом. Если версия, доступная OnLine более
свежая, чем используемая клиентом - выдается сообщение с
предложением принять обновление. После подверждения
клиентом программа скачивает обновление из Web,
используя URL, извлеченного из принятого XML файла в
начале данной операции и сохраненный в специальном локальном
директории клиента.
В этой точке процесса запущенное приложение
должно завершить свою работу и запустить другое приложение, которое
обновит исполняемый модуль и снова запустит его. Это требуется по
той причине, что запущенный EXE файл заблокирован в процессе
выполнения и не может быть перезаписан. Таким образом, текущее
приложение закрывается и стартует программа обновления приложения.
Данная программа обновления берет на себя замену оригинального
выполняемого EXE файла путем разархивирования обновленных
файлов в специальный директорий и последующая замена
программного EXE файла а так-же всех дополнительных файлов, которые
необходимы для работы Вашего приложения. Эта-же программа запускает
снова оригинальное приложение, которое в момент нового старта будет
уже иметь последний номер версии и пройдет без обновления очередное
сравнение номера версии, записанного в XML файле на Web сервере
обновлений.
Если у нас есть необходимость провести
однократно какое-то дополнительное действие, например изменение
структуры данных, обновление или вствака данных в справочники, это
может быть осуществлено после первого старта новой версии
приложения. Данный вид действия требует чтобы наше приложение
сохраняло обновляемый номер версии программы и версии данных в
файле конфигурации для сравнения их обоих. Если они не совпадают, то
запускается специальный код который связан с обновлением версии
данных. |
Класс wwCodeUpdate берет на себя большую часть процесса
обновления со всего несколькими свойствами и простыми методами.
Путем назначения свойств данного класса мы определяем где обновление
должно выполняться и к каким файлам обращться на Web и где их
так-же устанавливать. В дополнение наш класс использует XML файл на
сервере как источник версии и указатель какой файл надо загружать с
сервера, что делает возможным иметь для обновления несколько версий
одновременно (например многоступенчатое обновление для очень старых
версий Вашей программы).
Перед тем, как мы окунемся в детальное изучение работы класса,
давайте рассморим схематичный код в Lising 1, использующий класс
wwCodeUpdate внутри клиентского приложения для проверки наличия
новой версии и установки последней. |
Listing 1 |
* SampleAppForm :: CheckForNewVersion()
LOCAL loUpdate, loAPI, lcURL, lnVersion
*** Запрашиваем URL который бедем в дальнейшем использовать для проверки версии
*** Например: http://www.sergey.couk/ww_update/orders_update.xml
loAPI= CREATEOBJECT("wwAPI")
lcUrl = loAPI.GetProfileString(FULLPATH("wwReader.ini"),"Main","VersionUpdateUrl")
loUpdate= CREATEOBJECT("wwCodeUpdate")
***Url где проверять наличие свежей версии (XML файл)
loUpdate.cVersionUrl = lcUrl loUpdate.cVersionType = "N" && Numeric Type
*** имя файла приложения для горячей замены
loUpdate.cExeFile ="orders.exe"
*** Возврат текущей доступной версии из XML файла
*** Установка свойств loUpdate object из XML
lnVersion = loUpdate.GetVersionInfo()
*** Если мы не можем получить номер версии с Web Server
IF lnVersion = 0
*** Не можем получить информацию о версии программы - выйти
*** Мы так-же можем показать ошибку: loUpdate.cErrorMsg RETURN ENDIF
*** Сравнить номер версии с
*** номером версии приложения - здесь свойство формы
*** Обычно используется .H установка, поле таблицы или объект конфигурации
IF lnVersion > THISFORM.nVersion
*** Покажем сообщение и предложим скачать обновление
IF MessageBox(loUpdate.cUserMessage + CHR(13) +
CHR(13) +; "Вы не желаете скачать и уствновить обновление программы? ("
; LTRIM(TRANSFORM(loUpdate.nFileSize,"999,999,999")) +
; "kb)",32+4,"Фирма Рога и Копыта")= 6
IF !loUpdate.DownloadUpdate()
MessageBox(loUpdate.cErrorMsg,48,"Download
Error") ELSE
*** Закрываем программу VFP
CLEAR EVENTS
RELEASE THISFORM
*** Запускаем CodeUpdate Exe и завершаем программу
loUpdate.RunUpdateExe(;
[WSCRIPT CodeUpdate.vbs "orders.exe" "] + ;
SYS(5) + CURDIR() +;
[codeupdate\wwReader_Update.exe /auto ] + ;
SYS(5) + CURDIR() + [" ] + ;
["Фирма Рога и Копыта"])
ENDIF
ENDIF
ENDIF
RETURN
|
Приведенный выше код начинается с создания
wwCodeUpdate класса и получения URL для проверки необходимости
обновления из INI файла. Это значение может поступить откуда угодно
- DBF таблицы конфигурации, регистра, XML файла и т.д. - но мы
предпочтем управлять этим значением наиболее простым способом,
так что будет возможно изменить место нахождения
файла для различных версий или в период тестирования на локальном
сервере. Этот URL указывает на XML файл, размещенный на
Web сервере и содержит информацию о последней доступоной
версии программы, как это показано в Listing 2. |
Listing 2 |
<?xml version = "1.0"?>
<codeupdate>
<version>1.001</VERSION>
<usermessage>Новая версия 1.001 готова для обновления</usermessage>
<fileurl>http://www.sergey.couk/ww_update/orders_update.exe</fileurl>
<size>372</size>
</codeupdate>
|
Метод GetVersionInfo() загружает этот XML
файл и присваивает значения полученные из него некоторым свойствам
класса. Вам необходимо установить следующие свойства класса до
вызова этого метода: |
|
|