Заміна файлів .dll під час роботи програми?


18

У мене є кілька ігрових серверів, які використовують для запуску певний .dll файл. Іноді мені потрібно оновити ігрові сервери, але я не хочу переривати ігри, які вже запущені.

Чи є спосіб замінити .dll файл (він заблокований Windows), тому наступні екземпляри ігрових серверів, які використовують цей файл, відкривають нову версію, а старі продовжують використовувати стару версію цього .dll до їх перезапуску. ?

Чи безпечно просто розблокувати файл за допомогою одного з тих інструментів, які це роблять, і замінити його?


Можливо, не ваша гра. Однак Chrome робить оновлення , не перериваючи процес. На жаль, це застосування специфічно. (Перейдіть, %LocalAppData%\Google\Chrome\Applicationі вам слід побачити папки, на зразок 26.0.1410.64яких зберігаються DLL- файли різних версій)
Alvin Wong

Залежно від відповідного програмного забезпечення, можливо встановити та запустити два чи більше різних екземпляра (у різних місцях). Неефективна, але, можливо, працездатна.
Гаррі Джонстон

Відповіді:


23

Насправді, ви можете, і це, як правило, працює без будь-якого питання (хоча не завжди)

Що ви робите, це перейменувати файл, не переміщуючи його, і переміщувати новий файл над ним. Це дозволить зберегти ручки до файлу дійсними та працюючими, так що попередні екземпляри все ще зможуть належним чином отримати доступ до файлу, а нові екземпляри (або нові ручки) перейдуть до нового файлу.

Очевидно, якщо програма повторно відкриває той самий файл dll і очікує, що він залишиться абсолютно таким же (наприклад, якщо є ресурси, які потрібно завантажувати з dll, і посилання на ці ресурси витягуються з коду, що працює під час завантаження dll. ), це спричинить проблему, але це, безумовно, не є нормою.


11

Ні. Навіть незважаючи на те, що DLL може бути повністю відображена у фізичній пам'яті під час роботи програми, напевне, гарантії цього немає. Частини DLL (і навіть виконувані файли) можуть бути відображені в оперативній пам'яті, тоді як інші її біти залишаються на диску, і їх можна буде прочитати пізніше.

Зміна файлу на диску, коли Windows має його біти, відображені в оперативній пам'яті, не закінчиться добре. Windows блокує його з поважної причини.

Редагувати: Мені потрібно щось уточнити, оскільки, здається, деякі люди звинувачують Windows у тому, що насправді є проблемою дизайну додатків , а не проблемою дизайну ОС.

Ви можете оновити DLL, які програми використовують у Windows, не припиняючи процес, але програма повинна бути написана таким чином, щоб можна було сигналізувати про вивантаження збірки, дочекатися завершення оновлення та перезавантажити DLL. Це не має нічого спільного з ОС, яку ви працюєте. Це питання дизайну додатків.

Редагувати: Дивіться також відповідь Стефана щодо можливого рішення, яке може працювати, залежно від того, як ваша конкретна програма реагує на зміну DLL. Я думаю, що він заслуговує на надбавку.


Чи є спосіб перенести цей файл у тимчасове місце, щоб він міг бути видалений пізніше, при цьому розміщуючи новий у своєму старому місці (так що сервери, які починаються після цього, будуть використовувати новий dll)? Або ручка файлу пов'язана з розташуванням файлу?

Це повністю залежить від того, як написано додаток / як він використовує DLL. Подивіться на відповідь Грега Аскеу. Якщо ручка файлу відкрита, ви не можете багато з цим зробити. Ви можете примусово закрити ручку файлу, але ви майже напевно зламаєте принаймні ваш додаток, якщо не всю ОС.
Ryan Ries

То що це за «вагома причина»? Поки ваша відповідь не містить переконливої ​​причини, чому Microsoft не пропонує можливість гарячої заміни.
Конрад Рудольф

2

Ні, вам не слід повозитися з існуючими ручками файлів.

Якщо ви можете взяти під контроль завантаження збірки і вказати, що вона відкрита за допомогою FileShare.Delete, тоді слід перейменувати її. Існуючі процеси продовжуватимуть посилатися на перейменовану збірку.

/programming/7147577/programmatic-rename-open-file-on-windows .


2
На мій досвід, у більшості випадків (ну, більше, ніж у половині часу, у будь-якому випадку) ви можете перейменовувати (але не видаляти) DLL, не торкаючись програми.
Гаррі Джонстон

@HarryJohnston: Так, здається, я можу перейменувати .dll, навіть якщо він використовується. Я думаю, що я буду робити це відтепер.

1

Ні, на жаль це неможливо.

Вибачте, якщо бути точним, якщо немає пізнього прив'язки, тобто додаток використовує цей dll, коли виконує якусь частину коду в цьому dll, але він все ще не є надійним.


1

Ви можете подивитися, як працює процес asp.net, і розробити щось подібне.

Він бере весь веб-додаток і переміщує його у тимчасове місце, з якого програма фактично завантажується. Потім він залишає процес для моніторингу змін у вихідній папці, коли виявляється, він створює новий екземпляр програми в новому тимчасовому місці та починає перенаправляти нові запити до цієї програми. Потім старий додаток буде вимкнено, як тільки очікувані запити будуть закінчені.

(Нітпікінг, так, це спрощений огляд речей. У більшості випадків IIS чергає на запити, поки новий додаток не зможе прийняти на себе)



0

NSIS Installer має один варіант, як Перемістити до темпу на машині перезавантаження, ОС позначає якийсь файл для переміщення в інше місце під час наступного завантаження, при наступному завантаженні машини ці позначені файли автоматично переходять на нове місце, яке ви вибрали раніше. Невеликий пошук цього питання зробить вас щасливими в цьому плані.


Ви можете дати повну відповідь у своїй відповіді замість того, щоб сказати ОП шукати рішення. Він не був би тут, питаючи, чи вже знайшов рішення. Спасибі.
Джон aka hot2use
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.