Orion9

|
Posted: Sun Sep 06, 2026 14:06 Post subject: |
|
|
AkulaBig
Ну что, заработал у вас болван?
Я у него спросил, кстати:
 Hidden text Total Commander неи меет встроенной глобальной настройки, которая позволяла бы изолировать плагины и запускать их вне главного процесса приложения.Поскольку официальный SDK Total Commander компилирует плагины как стандартные динамические библиотеки Windows (файлы .wlx, .wfx, .wdx, .wcx — это просто переименованные .dll), они загружаются напрямую в адресное пространство памяти totalcmd.exe. Критическая ошибка (краш) внутри криво написанного плагина неизбежно приведет к падению главной оконной процедуры самого Total Commander.
Тем не менее, в зависимости от вашей цели (предотвратить зависания, избежать падений или использовать несовместимые плагины), существуют следующие варианты обхода и архитектурные решения
Реализация прокси-заглушки (Out-of-Process Proxy/Wrapper)
Если вы сами разрабатываете плагин и хотите гарантировать, что он никогда не обрушит главный поток хост-приложения, вам необходимо спроектировать его по клиент-серверной архитектуре:DLL-заглушка (In-Process): Вы пишете сам плагин .wlx/.wfx как легковесную DLL-«заглушку». Единственная задача этой DLL — общаться с отдельным процессом через механизмы межпроцессного взаимодействия (IPC).Воркер (Out-of-Process): Вы создаете отдельный исполняемый файл .exe, который и выполняет всю тяжелую работу.
Взаимодействие: Когда Total Commander вызывает функцию в вашей DLL-заглушке, эта DLL запускает ваш .exe (или связывается с уже запущенным экземпляром) через разделяемую память (Shared Memory), именованные каналы (Named Pipes) или сообщения WM_COPYDATA. Если .exe упадет, ваша DLL-заглушка сможет изящно перехватить эту ошибку и вернуть в Total Commander уведомление о сбое вместо того, чтобы обрушить всю программу.
Если создавать отдельный поток (thread) внутри той же DLL, это не защитит Total Commander от падения. В архитектуре Windows все потоки одного процесса делят между собой общее адресное пространство памяти. Если в коде плагина (даже в отдельном потоке) произойдет критическая ошибка вроде Access Violation (Segmentation Fault) или утечка памяти, операционная система завершит работу всего процесса totalcmd.exe целиком.
Именно поэтому для полной изоляции и стабильности необходимо использовать исключительно отдельный процесс (.exe).
Почему поток не спасет от падения, но полезен для отзывчивостиЧтобы четко понимать разницу в подходах, их можно разделить на две категории:
- Отдельный поток (Thread) — спасает только от "зависания" интерфейса
Если плагин делает долгий запрос к сети или обрабатывает гигантский файл, выполнение этого кода в отдельном потоке внутри DLL сохранит интерфейс Total Commander отзывчивым (главное окно не будет писать "Не отвечает"). Но если этот поток упадет — упадет и весь Total Commander.
- Отдельный процесс (.exe) — спасает от "смерти" приложения
Поскольку операционная система полностью изолирует память процессов друг от друга, краш, деление на ноль или зависание в вашем .exe никак не повлияет на totalcmd.exe. Процесс плагина просто завершится, а DLL-заглушка (Stub) получит уведомление о разрыве соединения и сможет корректно вывести пользователю сообщение: "Произошла ошибка при загрузке плагина".
Если вы пишете плагин (например, Lister .wlx), архитектура взаимодействия должна выглядеть следующим образом:
1. Инициализация: Total Commander вызывает функцию плагина (например, ListLoad).
2. Запуск воркера: Внутри этой функции DLL-заглушка вызывает Windows API функцию CreateProcess, запуская ваш скрытый worker.exe.
3. Передача данных: DLL передает в .exe параметры (путь к файлу, дескриптор окна hWnd для отрисовки) через один из механизмов IPC (Inter-Process Communication). Для плагинов просмотра чаще всего используют:
* WM_COPYDATA — самый простой способ передать кусок памяти или строку между окнами разных процессов.
* Named Pipes (Именованные каналы) — отлично подходит для постоянного стриминга данных.
* Shared Memory (Разделяемая память / File Mapping) — идеальный вариант, если нужно передавать большие объемы данных (например, текстуры или тяжелые документы) без накладных расходов на копирование.
4. Отрисовка (для Lister): Чтобы worker.exe мог рисовать прямо внутри панели Total Commander, DLL-заглушка должна передать ему hWnd родительского окна, которое ей выдал Total Commander. Затем .exe привязывает свое окно к родительскому с помощью функции SetParent(child_hwnd, parent_hwnd).
Вы планируете реализовать такую схему самостоятельно? Напишите, какой именно тип плагина (Lister, Content, Packer) вы разрабатываете и на каком языке программирования (C++, Delphi, C#) — я могу набросать базовый шаблон кода для DLL-заглушки и IPC-взаимодействия.
Решение с потоками рабочее. Например, была функция, которая выводит сведения о кодировке в кастомное поле
| Code: | Func EncDetect(FileName, FieldIndex, UnitIndex)
Local pipe
Static exe_tool = COMMANDER_PATH & "\Ini\Tools\uchardet.exe"
ProcessExecGetOutput pipe %exe_tool% '"%FileName%"'
Return pipe
EndFunc |
Если файл с текстом большой (>1 Гб), то это заметно вешает ТС при отображении подсказки. Но если переделать в поток, то фризов нет - интерфейс продолжает быть полностью доступным для работы
| Code: | Func EncDetect(FileName, FieldIndex, UnitIndex)
Global gEncDetect = 1, gEncPipe
RunThread("ThreadEncDetect", FileName, FieldIndex, UnitIndex)
While gEncDetect
Sleep(50)
Wend
Return gEncPipe
EndFunc
Func ThreadEncDetect(FileName, FieldIndex, UnitIndex)
Static exe_tool = COMMANDER_PATH & "\Ini\Tools\uchardet.exe"
ProcessExecGetOutput gEncPipe %exe_tool% '"%FileName%"'
gEncDetect = 0
EndFunc |
Это очень грубый пример, но сама идея рабочая.
Что касается других плагинов.
Да, может быть такая строчка в подсказке
| Code: | 21exts=>Текстовые файлы
21fields=Тип: [=encinfo.Type]\nКодировка: [=encinfo.Encoding]\nКодировка: [=autorun.Encoding] |
Т.е. помимо кода Авторан, выводятся данные из других плагинов (в данном случае EncInfo). Их тоже можно завернуть в Авторан при помощи объекта Plugin.
Можно сделать более продвинутый код, чтобы подсказка не отображалась (возвращала "") при смене позиции или по таймауту, но даже так уже гораздо лучше, чем наблюдать эти чудовищные фризы. Вообще удивляет, что маестро тратит время на всякую ерунду типа встроенного 7z, и ничего не делает для более комфортного существования в самом ТС. |
|