| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Добавить ресурс в запущенную программу |
| Автор: Gwire 11.4.2011, 13:10 |
| Тем похожих полно. Но все они о добавлении данных в ресурс до компиляции. Не исключено, что есть тема котора решает мою проблему, но среди тех "похожих"... я просто устал их перечитывать. Предисловие: Уже разработан и "принят на вооружение" класс (TCustomFormatStr), который загружает язык интерфейса и делает он это из ресурса. Получается так, в зависимости от того какой файл был добавлен в ресурс до компиляции такой и будет язык интерфейса проекта. Ресурс который он ищет - "FormatStr". Просто взять и поменять эту логику я не могу. Задача: Сделать загрузку язык интерфейса призапуске программы, а не в момент компиляции. Не добавлять файл с языком до компиляции, а держать их отдельно от программы. [ OK ] Компилировать и запустить программу [ OK ] Добавить ресурс "FormatStr" из файла выбранного пользователем [ FAIL ] Возможно ли вообще добавлять ресурсы уже воврмя работы программы? |
| Автор: RomanEEP 11.4.2011, 14:15 |
| Думаю что изменять экзешник во время выполнения недопускается. И вообще пытаться загрузить данные в ресурсы, а потом из ресурсов считывать метод прямо говоря кривой. Гораздо лучше сделать класс TCustomFormatStr абстрактным и реализовать наследники, кот позволяют ему работать как с файлами, так и с ресурсами |
| Автор: Gwire 11.4.2011, 14:49 |
Истинно так. Но увы я не могу менять это класс "TCustomFormatStr". Всмысле я могу - но нельзя. А сам экзешник менять не нужно. Нужно динамически подгрузить "файл языка" в ресурс HInstance. |
| Автор: cat512 12.4.2011, 00:06 |
| Как вариант использовать алгоритм packer-a/unpacker-a, но сложно всё это |
| Автор: bems 12.4.2011, 03:55 |
| Если нельзя менять только потому что во многих других местах завязано, то можно изменить минимально - добавить возможность загружать не только из своего HInstance, а из любого. Ну и сделать файлы переводов ресурсными дллками Также можно перезаписывать ресурс в памяти, но для этого длина нового ресурса не должна превышать длины старого. |
| Автор: northener 12.4.2011, 04:35 | ||
А вот тут желательно было дать либо ссылку, либо пример. Ибо мне, например, такой вариант пока не встречался. |
| Автор: bems 12.4.2011, 07:39 |
| northener, дам объяснение на пальцах. LockResource на самом деле возвращает указатель на ресурс, спроецированный на АП процесса вместе со всем исполняемым модулем. По этом адресу и можно перезаписать SizeofResource байт. Атрибуты защиты памяти обычно не позволяют этого сделать, поэтому нужно сперва сделать VirtualProtect этой области. То что последовательность FindResource-LoadResource-LockResource ничего фактически не загружает, а всего лишь находит указатель на ресурс, присутствующий в АП с самой загрузки модуля, и что это всегда один и тот же указатель для одного и того же ресурса в интервале загрузка модуля-выгрузка модуля нигде не документировано, но подтверждается практикой. Добавлено через 6 минут и 27 секунд Не даром же в MSDN сказано что FreeResource не нужна начиная с 32хбитных винд. Во времена х16 не было раздельных адресных пространств, и так появилась такая сложная последовательность работы с ресурсами. А с появлением виртуальных АП ресурс сразу же проецируется, и пока не будет нужен может при этом отсутствовать в оперативе. Загрузку возьмет на себя механизм подкачки. |
| Автор: MetalFan 12.4.2011, 12:13 |
| Вроде как BeginUpdateResource/EndUpdateResource позволяют менять ресурсы для НЕЗАПУЩЕННОГО исполнительного файла или dll. Так что можно реализовать следующий вариант: 1. Необходимо заменить некий ресурс в работающем exe. 2. запускаем вспомогательное приложение, которому передаем необходимую информацию (какой ресурс на что менять, к примеру), закрываемся. 3. Вспомогательное приложение апдейтит/заменяет языковой ресурс в исходном файле (с пом.упомянутых функций) и запускает исходное приложение. |
| Автор: Gwire 12.4.2011, 12:55 |
Я уже думал над этим вариантом... Если нет механизма добавления новых ресурсов в процессе работы - то он самый приемлемый. Хотя я нашел 3 функции: BeginUpdateResource, UpdateResource и EndUpdateResource. Вроде в MSDN-е описано все врозумительно, и на значение всех параметров понятно. =( но не срабатывает. PS: Буду пока делать с dll-ками. Добавлено через 7 минут и 6 секунд MetalFan, прошу прощения, почему то не увидел твоего сообщения. Теперь, после про чтения, становится ясно, что я не правильно делал. Я BeginUpdateResource указывал имя файла с языком, а не .exe-файл. |
| Автор: MetalFan 12.4.2011, 13:03 |
Я в свое время вполне удачно этими функциями пользовался. Все прекрасно работало. |