Автоматическая проверка наличия новой версии моего приложения

StackOverflow https://stackoverflow.com/questions/56391

  •  09-06-2019
  •  | 
  •  

Вопрос

Пытаясь выполнить просьбу наших клиентов о новых функциях, я хотел бы, чтобы мое приложение при наличии Интернета проверяло на нашем веб-сайте наличие новой версии.

Проблема в том, что я понятия не имею, что нужно делать на стороне сервера.

Я могу себе представить, что мое приложение (разработанное на C++ с использованием Qt) должно отправить запрос (HTTP?) на сервер, но что будет отвечать на этот запрос?Думаю, чтобы пройти через брандмауэры, мне придется использовать порт 80?Это верно ?

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


@пилиф :спасибо за ваш подробный ответ.Для меня еще кое-что непонятно:

нравиться

http://www.example.com/update?version=1.2.4

Затем вы можете вернуть все, что захотите, возможно, также URL-адрес загрузки установщика новой версии.

Как мне что-то вернуть?Это будет страница php или asp (я ничего не знаю ни о PHP, ни об ASP, должен признаться)?Как я могу расшифровать ?version=1.2.4 часть, чтобы соответственно что-то вернуть?

Это было полезно?

Решение

Я бы настоятельно рекомендовал просто выполнить простой HTTP-запрос на ваш сайт.Все остальное обречено на провал.

Я бы сделал запрос HTTP GET на определенную страницу вашего сайта, содержащую версию локального приложения.

нравиться

http://www.example.com/update?version=1.2.4

Затем вы можете вернуть все, что захотите, возможно, также URL-адрес загрузки установщика новой версии.

Почему бы просто не разместить статический файл с последней версией на сервере и позволить клиенту решить?Потому что вы можете захотеть (или нуждаться) в контроле над процессом.Возможно, версия 1.2 не будет совместима с сервером в будущем, поэтому вы хотите, чтобы сервер принудительно обновил версию 1.3, но обновление с 1.2.4 до 1.2.6 может быть некритичным, поэтому вы можете предоставить клиенту необязательное обновление.

Или вы хотите иметь разбивку по установленной базе.

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

Говоря здесь, имея небольшой опыт работы в этой области, вот небольшой обзор того, что может (и поверьте мне, будет) пойти не так:

  • Различные приложения персонального брандмауэра не позволят вашему приложению выполнять HTTP-запросы.
  • Значительный процент пользователей не будет иметь необходимых разрешений для фактического запуска процесса обновления.
  • Даже если ваши пользователи разрешили старой версии пройти через свой личный брандмауэр, указанный инструмент будет жаловаться, потому что .EXE изменился, и порекомендует пользователю не разрешать подключение нового exe (здесь пользователи обычно выполняют пожелания своего инструмента безопасности). .
  • В управляемых средах вас застрелят и повесят (не обязательно в указанном порядке) за загрузку исполняемого контента из Интернета и его последующее выполнение.

Поэтому, чтобы ущерб был как можно меньшим,

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

Делать то, что собираешься сделать, неинтересно, особенно когда имеешь дело с пользователями, не подкованными в технических вопросах, как мне приходилось делать много раз.

Другие советы

Ответ Пилифа был хорошим, и у меня тоже большой опыт в этом, но я хотел бы добавить еще кое-что:

Помните, что если вы запустите yourapp.exe, то «программа обновления» попытается перезаписать yourapp.exe самой новой версией.В зависимости от вашей операционной системы и среды программирования (вы упомянули C++/QT, у меня нет опыта работы с ними), вы будете нет иметь возможность перезаписать yourapp.exe потому что он будет использоваться.

Что я сделал, так это создал лаунчер.У меня есть MyAppLauncher.exe, который использует файл конфигурации (xml, очень простой) для запуска «настоящего exe».Если существует новая версия, программа запуска может обновить «настоящий exe», поскольку он не используется, а затем перезапустить новую версию.

Просто имейте это в виду, и вы будете в безопасности.

Мартин,

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

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

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

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

в php все просто:

<?php
    if (version_compare($_GET['version'], "1.4.0") < 0){
        echo "http://www.example.com/update.exe";
    }else{
        echo "no update";
    }
?>

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

В вашем приложении у вас будет этот псевдокод:

result = makeHTTPRequest("http://www.example.com/update?version=" + getExeVersion());
if result != "no update" then
    updater = downloadUpdater(result);
    ShellExecute(updater);
    ExitApplication;
end;

Не стесняйтесь расширять «протокол», указав что-то, что PHP-скрипт может вернуть, чтобы сообщить клиенту, является ли это важным, обязательным обновлением или нет.

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

Ваши возможности совершенно безграничны.

Мое приложение Qt просто использует QHttp для чтения крошечного XML-файла с моего веб-сайта, содержащего номер последней версии.Если он больше текущего номера версии, появляется возможность перейти на страницу загрузки.Очень просто.Работает отлично.

Я бы согласился с ответом @Martin и @Pilif, но добавил;

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

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

У нас была система EPOS, работающая примерно в 400 магазинах, и изначально мы подумали, что было бы здорово иметь точечные обновления программы и загружать их (используя файл, содержащий номер версии, очень похожий на предложения, которые вы дали выше)...отличная идея.До тех пор, пока все магазины не запустили свои системы примерно в одно и то же время (8:45-8:50 утра), и наш сервер не был поражен, обслуживая загрузку размером более 20 МБ на 400 удаленных серверов, что затем обновило бы локальное программное обеспечение и вызвало бы ошибку. перезапуск.Хаос – никто не может торговать в течение примерно 10 минут.

Излишне говорить, что это заставило нас впоследствии отключить функцию «проверки обновлений» и изменить ее дизайн, чтобы магазины могли «отложить» обновление до более позднего дня.:-)

РЕДАКТИРОВАТЬ:И если кто-то из ADOBE читает - ради бога, почему эта проклятая программа чтения Acrobat настаивает на попытке загрузить обновления и прочую ерунду, когда я просто хочу запустить ее, чтобы прочитать документ?Разве он не достаточно медленный при запуске и достаточно раздутый, чтобы не тратить еще 20-30 секунд своей жизни на поиск обновлений каждый раз, когда я хочу прочитать PDF-файл?
НЕ ИСПОЛЬЗУЮТ СОБСТВЕННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ??!!! :-)

На сервере у вас может быть простой файл «latestversion.txt», который содержит номер версии (и, возможно, URL-адрес загрузки) последней версии.Затем клиенту просто нужно прочитать этот файл, используя простой HTTP-запрос (да, к порту 80), чтобы получить http://your.web.site/latestversion.txt, который затем можно проанализировать, чтобы получить номер версии.Таким образом, вам не понадобится какой-либо причудливый серверный код — вам просто нужно добавить простой файл на существующий веб-сайт.

Если вы храните свои файлы в каталоге обновлений на сайте example.com, этот PHP-скрипт должен загрузить их для вас, учитывая ранее упомянутый запрос.(ваше обновление будет yourprogram.1.2.4.exe

$version = $_GET['version'];    
$filename = "yourprogram" . $version . ".exe";
$filesize = filesize($filename);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: post-check=0, pre-check=0");
header("Content-type: application-download");
header('Content-Length: ' . $filesize);
header('Content-Disposition: attachment; filename="' . basename($filename).'"');
header("Content-Transfer-Encoding: binary");

Это заставляет ваш веб-браузер думать, что он загружает приложение.

Самый простой способ сделать это — запустить HTTP-запрос, используя такую ​​библиотеку, как библиотека libcurl и загрузите файл ini или xml, который содержит онлайн-версию и где новая версия будет доступна в Интернете.

После анализа XML-файла вы можете определить, нужна ли новая версия, загрузить новую версию с помощью libcurl и установить ее.

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

Я думаю, что простого XML-файла на сервере будет достаточно только для целей проверки версии.

В этом случае вам понадобится только учетная запись FTP на вашем сервере и система сборки, которая сможет отправлять файл через FTP после создания новой версии.Эта система сборки может даже разместить установочные файлы/zip-архив прямо на вашем веб-сайте!

Если вы хотите сохранить его по-настоящему простым, просто загрузите файл version.txt на веб-сервер, который содержит целочисленный номер версии.Загрузите эту проверку на соответствие последней загруженной вами версии файла.txt, а затем просто загрузите MSI или установочный пакет и запустите его.

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

По сути, вам просто нужна простая функция загрузки.

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

Существует несколько коммерческих решений для автоматического обновления.Я оставлю рекомендации для других ответчиков, потому что у меня есть опыт работы только на стороне .net с Click-Once и блокировкой приложений Updater (последний больше не продолжается).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top