Не блокировать файлы приложения во время работы

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

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

Есть ли простой способ решить эту проблему? Это устаревшее приложение, и у меня нет времени изменять большие части приложения или механизм обновления.

4 ответа

Решение

Простым решением было бы использовать теневое копирование.

Простой пример:

class Program
{
    static void Main(string[] args)
    {
        var x = AppDomain.CreateDomain("TestAssembly", null, new AppDomainSetup() { 
                                                            ShadowCopyFiles = "true",
                                                            CachePath = @"c:\tmp", 
                                                            ApplicationName = "ShadowCopyTest"
                                                       });
        var a = x.Load("TestAssembly"); // Load Assembly and run...
    }
}

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

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

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

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

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

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

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

Что ж, Windows позволяет вам переименовывать соответствующие файлы, даже если они используются. Таким образом, вы можете переименовать обновленные файлы, заменить их новой версией и перезапустить приложение.

Я думаю, вы не сможете решить эту проблему без изменения механизма обновления.

Я предполагаю, что вы загружаете сборки непосредственно вместо старых сборок. Допустим, у вас есть сборка myprogram.dll. Сначала загрузите новую обновленную dll с другим именем (например, _myprogram.dll) . Запустите событие после завершения загрузки, которое заменит myprogram.dll на _myprogram.dll. Это событие должно сначала объявить все запущенные процессы, а затем заменить сборки. замена должна занять в данный момент. Вы не можете избежать сокращения услуг в этот момент.

РЕДАКТИРОВАТЬ:

Должен быть процесс, который всегда будет запускаться и проверять наличие обновлений. Сначала отправьте имя файла этому процессу. Теперь процесс будет загружать, например, 5 файлов. Процесс должен загружать файлы в предопределенном формате имен (например, объединять его с подчеркиванием) . После того как процесс завершит загрузку 5-го файла, он должен уничтожить все другие процессы (или, предпочтительно, только процессы, связанные с загруженными сборками), а затем заменить сборки на новые. Чем начать процессы снова.

Другие вопросы по тегам