Вопрос по .net, self-updating – Не блокировать файлы приложения во время работы

3

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

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

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

Ваш Ответ

4   ответа
1

Простое решение будет использоватьТеневое копирование.

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

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...
    }
}

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

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

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

Я сделал быструю проверку, и это похоже на работу. Мне нужно будет продолжить тестирование, но Shadow Copying кажется многообещающим ...
Спасибо, я думаю, что это будет разумный подход!
3

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

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

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

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

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

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

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

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

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

ED & # x130; Т:

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

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

Похожие вопросы