У меня есть несколько игровых серверов, которые используют для запуска определенный файл .dll. Иногда мне нужно обновить игровые серверы, но я не хочу прерывать уже запущенные игры.
Есть ли способ заменить файл .dll (он заблокирован Windows), чтобы следующие экземпляры игровых серверов, которые используют этот файл, открывали новую версию, а старые продолжали использовать старую версию этой .dll до тех пор, пока они не будут перезапущены ?
Безопасно ли просто разблокировать файл с помощью одного из этих инструментов и заменить его?
Собственно, можно и это обычно работает без проблем (хотя и не всегда)
Что вы делаете, так это переименовываете файл, не перемещая его, и перемещаете новый файл поверх него. Это сохранит дескрипторы файла действительными и работающими, так что уже существующие экземпляры смогут правильно обращаться к файлу, а новые экземпляры (или новые дескрипторы) перейдут к новому файлу.
Очевидно, если программа повторно открывает тот же файл DLL и ожидает, что он останется точно таким же (например, если есть ресурсы, которые нужно загрузить из DLL, и что ссылки на эти ресурсы извлекаются из кода, выполняющегося при загрузке DLL ), это вызовет проблемы, но это определенно не норма.
Нет. Хотя DLL может быть полностью отображенным в физической памяти во время работы приложения, нет никакой гарантии этого. Части DLL (и даже исполняемые файлы) могут быть отображены в RAM, в то время как другие ее биты остаются на диске и могут быть прочитаны позже.
Изменение файла на диске, когда в Windows есть его биты, отображенные в ОЗУ, не закончится хорошо. Windows блокирует его по уважительной причине.
Изменить: мне нужно кое-что прояснить, поскольку некоторые люди, похоже, намерены обвинять Windows в том, что на самом деле является применение проблема дизайна, а не проблема дизайна ОС.
Вы можете обновлять библиотеки DLL, которые приложения используют в Windows, не прерывая процесс, но приложение должно быть написано таким образом, чтобы можно было получить сигнал о выгрузке сборки, ожидании завершения обновления и перезагрузке библиотеки DLL. Это не имеет ничего общего с используемой вами ОС. Это проблема дизайна приложения.
Изменить: также см. Ответ Стефана для возможно решение, которое мощь работать, в зависимости от того, как ваше конкретное приложение реагирует на изменение своей DLL. Я думаю, он заслуживает одобрения.
Нет, не стоит возиться с существующими дескрипторами файлов.
Если вы можете взять под контроль загрузку сборки и указать, что она открыта с помощью FileShare.Delete, тогда ее можно будет переименовать. Существующие процессы по-прежнему будут ссылаться на переименованную сборку.
https://stackoverflow.com/questions/7147577/programmatically-rename-open-file-on-windows.
Нет, к сожалению, это невозможно.
Извините, если быть точным, если нет позднего связывания, то есть приложение использует эту dll при запуске некоторой части кода в этой dll, но это все еще ненадежно.
Вы можете посмотреть, как работает процесс, размещенный на asp.net, и разработать что-то подобное.
Он берет все веб-приложение и перемещает его во временное место, из которого оно фактически загружается. Затем он оставляет процесс для отслеживания изменений в исходной папке, при обнаружении запускает новый экземпляр приложения в новом временном местоположении и начинает перенаправлять новые запросы в это приложение. После обработки ожидающих запросов старое приложение удаляется.
(Nitpicking, да, это упрощенный взгляд на вещи, в большинстве случаев IIS ставит запросы в очередь до тех пор, пока новое приложение не сможет взять на себя)
Около десяти лет назад я был счастливым пользователем http://www.eggcentric.com/ISAPILoader.htm который действительно жил подкачкой dll IIS ISAPI. Г-н Эгг все еще поддерживает свое решение FOSS.
В установщике NSIS есть одна опция: «Переместить в временную папку при перезапуске машины», ОС помечает какой-либо файл для перемещения в другое место при следующей загрузке, при следующей загрузке машины эти помеченные файлы автоматически перемещаются в новое место, которое вы выбрали ранее. Небольшой поиск по этому поводу сделает вас счастливыми в этом отношении.