Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
1

Автообновление программы

14.03.2019, 22:21. Показов 3017. Ответов 5

Author24 — интернет-сервис помощи студентам
Всем привет, появился такой вопрос.. Сейчас у меня есть программа с автообновлениями, но написанными на коленке, т.е просто каждый раз для новой версии я в коде устанавливаю на версию выше, вручную, и при каждом запуске программа сверяет эту версию с json в котором указана самая новая и в случае несовпадения качаются все файлы, ссылки на которые прикреплены к данному json. Все ссылки опять же прикрепляю вручную

Вопрос такой, как сделать нормально?) В идеале вижу сервер, на котором лежат файлы, какая-то апишка, которая возвращает хеши всех файлов из папки обновлений + ссылки на них, программа принимает и сверяет с локальными и качает те, что требуются в папку update , потом закрывается и открывает updater, updater.exe заливает все файлы из папки update с заменой в текущую и запускает основной ехе

Подскажите как такое реализовать. С .Net core и web api знаком
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.03.2019, 22:21
Ответы с готовыми решениями:

Автообновление программы
Сделал апдейтер для программы, и сейчас вот дописываю поддержку обновления апдейтера. Проблема в...

Автообновление
Итак столкнулся с такой проблемой. Моя программа обновляется практически каждый день(добавляются...

Автообновление службы ( сервиса )
Доброго времени суток уважаемые читатели ! Начал писать службу для обработки пакетов WebSocket...

Автообновление
возможно ли как то сделать чтобы через autoupdater с ftp качался не архив а папка содержащая в себе...

5
Эксперт .NETАвтор FAQ
10413 / 5143 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
15.03.2019, 00:26 2
Лучший ответ Сообщение было отмечено Usaga как решение

Решение

Цитата Сообщение от MakcPletnev Посмотреть сообщение
Подскажите как такое реализовать
Aвтообновление - штука сложная. Если приложение - достаточно простое, это не сервер, не системная утилита, не сервис, то лучше использовать ClickOnce.

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

1) Антивирусы. Эта фигня выпила мне не мало крови. Основная проблема в том, что он скорее всего не даст вам скидывать exe или dll в папку ProgramFiles. Кроме того, сам стартер лучше устанавливать через какой либо стандартный установщик. Я использую InnoSetup. Сам стартер устанавливается в ProgramFiles, далее он качает собственно само приложение, но устанавливает его не в ProgramFiles, а в AppData которое доступно на запись. Антивирь обычно не ругается на такие манипуляции.

2) Стартер не должен запускать целевое приложение через Process.Start(...). Почему? Потому что антивирусу это не понравится. А еще в диспетчере задач возникнет два процесса с одинаковым именем, что тоже не очень хорошо. Кроме того, возникнут проблемы, описанные ниже. У меня стартер запускает целевое приложение через создание отдельного AppDomain:
C#
1
2
3
4
    //create target domain
    var targetDomain = AppDomain.CreateDomain("TargetDomain", new Evidence(), preferredFolder, "", false);
    //start target
    targetDomain.ExecuteAssembly(exe);
3) Если запускать целевое приложение через Process.Start(...), то возникают следующие проблемы:
- Конфиг файл, который лежит рядом со стартером - не подхватится. Потому что само приложение - в 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, его автоматически создает стартер.


Цитата Сообщение от MakcPletnev Посмотреть сообщение
которая возвращает хеши всех файлов из папки обновлений + ссылки на них, программа принимает и сверяет с локальными и качает те, что требуются в папку update
Я бы советовал качать все файлы целиком. А инкрементное обновление - это сложно и опасно. Скорее всего закончится тем, что приложение не сможет запуститься из-за того, что одни dll не будут совместимы с другими.
5
41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
15.03.2019, 11:11  [ТС] 3
Storm23, так если на сервере лежат все файлы , то почему может возникнуть проблема с инкрементным обновлением? Ведь например теже игры не перекачивают постоянно полный дистрибутив
У меня файлы программы не лежат в программфайл и appdata не используется. Вся папка находится в удобном для юзера месте , внутри неё есть 2 ехе, которые запускают программу из папки рядом с ними. Т.е 2 стартера и папка с самой программой
0
Эксперт .NETАвтор FAQ
10413 / 5143 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
15.03.2019, 11:27 4
Цитата Сообщение от MakcPletnev Посмотреть сообщение
так если на сервере лежат все файлы , то почему может возникнуть проблема с инкрементным обновлением?
Проблем может быть масса. Например, вы же не закачиваете все файлы на сервер одновременно?
Часть длл на сервере уже обновилась, а часть - нет. И в этот момент запускается апдейтер у клиента.
В результате часть длл он скачивает (потому, что они уже залились на сервер), а часть - нет (потому что они еще не залились на сервер). В результате - приложение падает из-за частичного обновления длл.
Также подумайте, что будет происходить, если пользователь запустит два стартера одновременно?
Что будет происходить если в момент обновления вырубился свет?
Что если пользователь запустил приложение без стартера, а затем запустил стартер?
Да там масса может быть вариантов.
Цитата Сообщение от MakcPletnev Посмотреть сообщение
У меня файлы программы не лежат в программфайл и appdata не используется. Вся папка находится в удобном для юзера месте
Это печально на самом деле.

Цитата Сообщение от MakcPletnev Посмотреть сообщение
Ведь например теже игры не перекачивают постоянно полный дистрибутив
Разработка игр стоит сотни тысяч баксов и более. Системой апдейта наверняка занимается отдельный программист. Ну или эта система просто покупается.

Нет, ну если вы хотите делать инкрементное обновление - пожалуйста. Я просто описал некоторые (кстати не все) проблемы которые возникнут на этом пути
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.06.2019, 09:08
Помогаю со студенческими работами здесь

Автообновление DataGridView
Здравствуйте, есть datagridview, куда выводится таблица. Как сделать автообновление?private async...

Автообновление БД из DataSet
Ситуация такова. Програмно обновляю DataSet из контрола (группы контролов). Интуитивно, по строению...

Некорректное автообновление datagrid
Доброго времени суток. Подскажите на ошибку в коде. делаю автообновление датагрида public...

Автообновление данных в Grid
Делаю многопользовательскую программу для учета. База SQL Server 2008. На главной форме у меня...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru