Подтвердить что ты не робот

Применить обновление без перезапуска приложения

Недавно у меня было интервью для позиции .NET. Из заданных вопросов у меня возникли проблемы с ответом на один вопрос. Надеюсь, кто-то может мне помочь в этом.

Сценарий (вопрос): первая версия приложения (может быть, это приложение winform/wpf UI) уже отправлено клиенту, и они начали использовать приложение. Но, к сожалению, команда QA позже нашла серьезную проблему в текущем выпуске. Теперь проблема в том, что мы должны иметь возможность отправлять и применять исправление (исправление), не заставляя приложение перезапускаться. Предполагается, что приложение представляет собой приложение реального времени, которое не может быть перезапущено для применения исправлений.

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

Ответ:

Спасибо за все, внесенные до сих пор. Мне удалось найти решение этой проблемы. Не уверен, спрашивал ли он интервьюер. Тем не менее, я рад прочитать о microsoft ClickOnce, который делает почти то, что я хотел.

4b9b3361

Ответ 1

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

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

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

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

Некоторые необычные методы, вероятно, будут полезны здесь, в зависимости от точного требования. Расширенное кэширование может позволить обнулить уровень данных, если интерфейс не потеряет способность отображать данные. Механизмы командной строки или надежные механизмы обмена сообщениями могут позволить пользовательскому интерфейсу оставаться отзывчивым, в то время как бизнес-уровень заменяется, и новый бизнес-уровень может обрабатывать очередь. Если вы предполагаете (логически) серверное приложение, то избыточность на каждом уровне может позволить одному избыточному "серверу" уровня обновляться, пока другой сервер продолжает обрабатывать... и т.д.

Ответ 2

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

Ответ 3

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

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

Ответ 4

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