Как обновить файлы приложения с помощью патчей?

Меня не интересуют какие-либо решения для автоматического обновления, такие как ClickOnce или MS Updater Block. Для тех, кто испытывает желание спросить, почему бы и нет: я уже использую их, и в них нет ничего плохого, я просто хотел бы узнать о любых эффективных альтернативах.

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

Само приложение может быть развернуто xcopy (чтобы избежать автоматического исправления MSI измененных файлов или нарушения подписей ClickOnce).

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

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

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

Существуют ли какие-либо решения для этого?

ПРИМЕЧАНИЕ. Есть несколько вопросов по SO, которые могут показаться дубликатами, но ни один из них не дает хорошего ответа.

Это вопрос о платформе Windows, желательно .NET.

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


person Marek    schedule 11.04.2010    source источник
comment
Большое спасибо за ссылку на wyUpdate, я давно искал такую ​​хорошую библиотеку!   -  person Lasse V. Karlsen    schedule 13.04.2010


Ответы (1)


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

      org+p1
     /      \
    + p1     +p2    <-- note, p2 is the same patch both places
   /          \
original       org+p1+p2
   \          /
    + p2     +p1    <-- ie. the p2 on this line is the same as the one above
     \      /
      org+p2

Вместо этого у вас будет такой сценарий:

      org v.2
     /      \
    +p1      +p4    <-- note, different patches now
   /          \
org v.1        org v.4
   \          /
    +p2      +p3
     \      /
      org v.3

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

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

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

                                      +-- most up to date version
                                      |            
                                      v
org v.1         org v.3             org v.4
   \           /       \           /
    +p1       +p2       +p3       +p4
     \       /           \       /
      org v.2             org v.4
       \
        +p1.1
         \
          org v.2 hotfix 1

Что касается фактического кода, у меня есть реализация diff / patch, но она, вероятно, далека от оптимальной. В настоящее время создание файлов исправлений для любого файла значительного размера занимает много времени. Патчи довольно маленькие, но я осмелюсь сказать, что другие алгоритмы дадут более качественные исправления. Примеры тестов с bsdiff и bspatch дают меньшие исправления.

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

person Lasse V. Karlsen    schedule 12.04.2010
comment
Спасибо за подробный анализ и ссылку на вашу дельта-реализацию. Я изучу код и постараюсь извлечь из него уроки. - person Marek; 13.04.2010