2012-06-08 5 views
3

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

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

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

ответ

1

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

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

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 должен быть специфичным для пользователя, например. каталог пользователей temp.

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

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

+0

Я сделал быструю проверку, и, похоже, она работает. Мне нужно будет протестировать дальше, но Shadow Copying кажется многообещающим ... –

+0

Спасибо, я думаю, что это будет разумный подход! –

1

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

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

+0

Я не могу просто «перезапустить приложение». Файлы заблокированы из-за других пользователей, запускающих приложение одновременно на сервере терминалов, как указано в моем вопросе. –

+1

Да, вы можете. Обновления устанавливаются, когда пользователь запускает приложение, не так ли? Таким образом, есть X экземпляры, на которых запущена старая версия, и одна из них обновляется путем переименования существующих файлов и копирования новых версий в папку установки. Если приложение затем вызывает 'Application.Restart()' один пользователь использует новую версию приложения и DLL, в то время как другие пользователи все еще используют старую версию до тех пор, пока они не перезапустят приложение. –

0

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

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

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

+0

Как должно выглядеть такое событие? Итак, в основном вы предлагаете постоянно запускать приложение под учетной записью администратора, а когда есть обновление, просто убейте процессы всех других пользователей? Я не думаю, что это где-то рядом с возможным вариантом ... –

+0

Я отредактировал свой ответ. –

+0

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

3

Большинство обновлений имеют исполняемый файл bootstrapper, который выполняет обновление основного приложения.

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

Другая техника (я никогда не пробовал, это всего лишь ключ) - использовать shadow assemblies.Концепция состоит в том, чтобы «дублировать» сборку в файле, чтобы избежать блокировки файла.

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

+0

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

+0

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

+0

Я посмотрю на ClickOnce, но я боюсь, что вам нужно установить приложение для каждого пользователя, а не только один раз? Проблема в том, что приложение является унаследованным приложением, уже запущенным несколькими десятками клиентов, поэтому нет места для больших изменений, подобных этому ... –

Смежные вопросы