Заміна файлів .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.