41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
|
|
1 | |
Автообновление программы14.03.2019, 22:21. Показов 3017. Ответов 5
Метки автообновление (Все метки)
Всем привет, появился такой вопрос.. Сейчас у меня есть программа с автообновлениями, но написанными на коленке, т.е просто каждый раз для новой версии я в коде устанавливаю на версию выше, вручную, и при каждом запуске программа сверяет эту версию с json в котором указана самая новая и в случае несовпадения качаются все файлы, ссылки на которые прикреплены к данному json. Все ссылки опять же прикрепляю вручную
Вопрос такой, как сделать нормально?) В идеале вижу сервер, на котором лежат файлы, какая-то апишка, которая возвращает хеши всех файлов из папки обновлений + ссылки на них, программа принимает и сверяет с локальными и качает те, что требуются в папку update , потом закрывается и открывает updater, updater.exe заливает все файлы из папки update с заменой в текущую и запускает основной ехе Подскажите как такое реализовать. С .Net core и web api знаком
0
|
14.03.2019, 22:21 | |
Ответы с готовыми решениями:
5
Автообновление программы Автообновление Автообновление службы ( сервиса ) Автообновление |
15.03.2019, 00:26 | 2 | |||||
Сообщение было отмечено Usaga как решение
Решение
Aвтообновление - штука сложная. Если приложение - достаточно простое, это не сервер, не системная утилита, не сервис, то лучше использовать ClickOnce.
Ну а если же хочется повелосипедить, то могу сразу описать проблемы, которые возникнут: 1) Антивирусы. Эта фигня выпила мне не мало крови. Основная проблема в том, что он скорее всего не даст вам скидывать exe или dll в папку ProgramFiles. Кроме того, сам стартер лучше устанавливать через какой либо стандартный установщик. Я использую InnoSetup. Сам стартер устанавливается в ProgramFiles, далее он качает собственно само приложение, но устанавливает его не в ProgramFiles, а в AppData которое доступно на запись. Антивирь обычно не ругается на такие манипуляции. 2) Стартер не должен запускать целевое приложение через Process.Start(...). Почему? Потому что антивирусу это не понравится. А еще в диспетчере задач возникнет два процесса с одинаковым именем, что тоже не очень хорошо. Кроме того, возникнут проблемы, описанные ниже. У меня стартер запускает целевое приложение через создание отдельного AppDomain:
- Конфиг файл, который лежит рядом со стартером - не подхватится. Потому что само приложение - в AppData, а стартер - в ProgramFiles. - Если вместе со стартером распространяются какие либо файлы данных, то целевое приложение тоже их не найдет. Потому что Application.StartupPath будет указывать не на папку стартера а на папку в AppData. - Если приложение уже запущено и работает, то оно не узнает о выходе новой версии. Потому что оно никак не получает информацию от стартера. Эти проблемы более-менее решаемы, если запускаться целевое приложение через AppDomain. 4) Самое главное - гарантированное обеспечение работоспособности приложения. Я достигаю это следующим образом: С сервера качается zip файл который содержит все файлы приложения. Далее, стартер создает отдельную папку в AppData имя которой совпадает с номером версии. При этом папка с предыдущей версией - не удаляется. Далее, если при запуске приложения возникают проблемы (например выпадает эксепшн), то стартер информирует пользователя о том, что с новой версией какая-то фигня, отправляет алерт разработчику, и предлагает пользователю запустить предыдущую версию. 5) Обновление самого стартера и/или URL-а с которого он загружает приложение. Это проблема. Ниже выдержка из тех. доки, которую я писал для апдейтера, там расписано все более подробно: Кликните здесь для просмотра всего текста
Система автообновления
Проект Starter содержит класс AutoUpdater, который выполняет функции обновления. Проект компилируется в exe файл, имя которого будет использоваться как имя устанавливаемой программы. Настройки проекта содержат поля: 1) UpdateURL – содержит URL zip архива, который содержит все файлы целевого проекта (протокол http). 2) CheckUpdateInterval – задает интервал, через который будет проведена проверка обновлений. Первая проверка – всегда при старте стартера. Архив zip должен содержать все файлы, необходимые для работы программы. В корне zip должен быть один exe файл, который будет автоматически запускаться, после старта стартера. В целевой папке также может содержаться файл настроек для целевого exe файла, он автоматически подхватывается и будет передан целевому exe. Zip файл должен содержать все файлы, необходимые для работы программы. Система автообновления не является инкрементной, так что файлы предыдущей версии не будут использоваться в новой версии. Стартер не вызывает проблем с антивирусами и пишет данные только в разрешенную на запись папку Environment.SpecialFolder.ApplicationData. В диспетчере задач будет показано имя процесса, совпадающее с именем exe файла стартера. Имя целевого exe нигде не отображается. Алгоритм работы стартера следующий: 1) В папке Environment.SpecialFolder.ApplicationData проверяется наличие папки, совпадающей с именем exe файла стартера (без расширения). Если папки нет, она создается. 2) В папке будут содержаться подпапки для каждой версии. 3) Если ни одной версии не найдено, будет искаться файл Update.zip в папке самого стартера. Если он есть, то zip распаковывается и считается первой загруженной версией. 4) Если файла Update.zip в папке стартера не найдено, будет качаться zip файл из указанного URL. Пользователю будет выдано сообщение ждать. 5) После того как первая версия скачана и распакована, в ней ищется exe файл и запускается. 6) Файл PreferredVersion содержит версию, которую выбрал пользователь (стартер спрашивает после загрузки новой версии). 7) Стартер удаляет все папки с версиями, кроме двух последних. 8) В папке версии находится распакованный zip файл. Стартер запускает exe файл в своем процессе, но в отдельном домене. Домену передается конфигурационный файл, для целевого exe. 9) После того, как целевая программа запущена, запускается отдельный поток, который будет проверять наличие обновления по указанному URL. С сервера читается дата модификации zip файла и его размер (через запрос HEAD). Если эти данные не совпадают с данными последнего загруженного zip файла, то считается что выпущена новая версия и zip файл качается целиком. Данные о загруженном zip файле хранятся в файле DownloadedVersionInfo внутри папки версии. 10) Скачанный файл распаковывается в AppData и в следующий раз при старте, стартер предложит пользователю запустить новую версию приложения. Версия читается из секции AssemblyVersion целевого exe файла. 11) Если загружена новая версия, стартер передает номер версии через окружение AppDomain в целевое приложение (которое уже запущено в момент загрузки новой версии). Прочитать можно так: var ver = AppDomain.CurrentDomain.GetData("NEW_VERSION"); Если ver не равно null, значит есть новая версия. Имя версии находится в ver. Подготовка целевого проекта Целевой проект не требует специальной подготовки. Для выпуска новой версии нужно: 1) Установить номер версии в AssemblyVersion в целевом exe (для самого апдейтера это не обязательно, но эта информация будет показываться пользователю). 2) Скомпилировать и запаковать все файлы в zip файл. Корень zip должен содержать exe файл. Имя zip может быть любым, но оно должно совпадать с именем, указанным в URL настройках стартера. Имя целевого exe файла – любое. 3) Загрузить zip на целевой HTTP сервер. Других подготовок не требуется. Заметьте: 1) Конфигурационный файл автоматически подхватывается. 2) В приложении Application.StartupPath будет показывать на стартер, а не на целевой exe файл. Для указания реальной папки, где находится exe – используйте AppDomain.CurrentDomain.BaseDirectory. 3) В папке не обязательно наличие файла DownloadedVersionInfo, его автоматически создает стартер. Я бы советовал качать все файлы целиком. А инкрементное обновление - это сложно и опасно. Скорее всего закончится тем, что приложение не сможет запуститься из-за того, что одни dll не будут совместимы с другими.
5
|
41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
|
|
15.03.2019, 11:11 [ТС] | 3 |
Storm23, так если на сервере лежат все файлы , то почему может возникнуть проблема с инкрементным обновлением? Ведь например теже игры не перекачивают постоянно полный дистрибутив
У меня файлы программы не лежат в программфайл и appdata не используется. Вся папка находится в удобном для юзера месте , внутри неё есть 2 ехе, которые запускают программу из папки рядом с ними. Т.е 2 стартера и папка с самой программой
0
|
15.03.2019, 11:27 | 4 |
Проблем может быть масса. Например, вы же не закачиваете все файлы на сервер одновременно?
Часть длл на сервере уже обновилась, а часть - нет. И в этот момент запускается апдейтер у клиента. В результате часть длл он скачивает (потому, что они уже залились на сервер), а часть - нет (потому что они еще не залились на сервер). В результате - приложение падает из-за частичного обновления длл. Также подумайте, что будет происходить, если пользователь запустит два стартера одновременно? Что будет происходить если в момент обновления вырубился свет? Что если пользователь запустил приложение без стартера, а затем запустил стартер? Да там масса может быть вариантов. Это печально на самом деле. Разработка игр стоит сотни тысяч баксов и более. Системой апдейта наверняка занимается отдельный программист. Ну или эта система просто покупается. Нет, ну если вы хотите делать инкрементное обновление - пожалуйста. Я просто описал некоторые (кстати не все) проблемы которые возникнут на этом пути
0
|
41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
|
|
15.03.2019, 11:49 [ТС] | 5 |
Storm23, я вас понял , буду думать) Спасибо)
0
|
0 / 0 / 0
Регистрация: 24.09.2013
Сообщений: 32
|
|
27.06.2019, 09:08 | 6 |
Здравствуйте! Тоже хочу сделать программу с обновлением. ЕХЕ файл лежит в файловом менеджере. Не подскажете как получить ссылку на файл? Спасибо!
0
|
27.06.2019, 09:08 | |
27.06.2019, 09:08 | |
Помогаю со студенческими работами здесь
6
Автообновление DataGridView Автообновление БД из DataSet Некорректное автообновление datagrid Автообновление данных в Grid Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |