Находим местоположение WINCMD.INI

Уважаемые авторы замечательных плагинов и полезных утилит!
Большинству из ваших программ требуется указание точного местоположения файла TOTALCMD.EXE и INI файлов настройки Коммандера.

Каждый автор ищет решение этой проблемы по своему:
Одни (самые умные :)) вообще ничего не ищут, а требуют от пользователя вручную заводить эти пути. Решение, конечно, крайне примитивное. И пользователь может ошибиться с указанием путей, да и тулза оказывается жестко привязанной к одному месту. Если пользователь имеет несколько настроенных профилей ТС, то он вынужден держать несколько копий вашей программы - для каждого профиля отдельно.
Другие (слава Богу - таких уже почти не осталось) тупо считают, что эти файлы могут называться только wincmd.ini
и wcx_ftp.ini и лежат они исключительно в %WINDIR%. Просто нет слов...
Третьи (кто посообразительней), пытаются анализировать содержимое ветки [HKEY_CURRENT_USER\Software\Ghisler\Total Commander]
и, увы, тоже не всегда бывают правы.
Этой мини-статейкой я попытаюсь проанализировать опыт тех и других и сделать некоторые выводы. Надеюсь, они пригодятся вам в дальнейших разработках.

Итак, начнем с самого простого - TOTALCMD.EXE

Он ВСЕГДА находится по %COMMANDER_PATH%/TOTALCMD.EXE
Учтите только, что %COMMANDER_PATH% имеется в переменных окружения только тогда, когда ваша прога стартует из ТС. Для авторов плагинов это всегда факт, утилита же может стартовать и не из ТС.
Уважаемые авторы, заставьте своего пользователя хотя бы в первый раз запустить вашу тулзу из ТС - она запишет найденный путь, и в дальнейшем ее можно будет стартовать откуда угодно. Поверьте, 99% пользователей будут запускать вашу утилиту именно из ТС, а автоматически найденный ею путь будет лишним доказательством вашего профессионализма!

Теперь про поиск INI файлов

Единственно правильный вариант на сегодня:

1.Анализируем командную строку ТС, ищем в ней ключи /I и /F и считываем пути к INI оттуда.
2.Если в командной строке ключи не найдены, то проверяем, есть ли в файле %COMMANDER_PATH%/wincmd.ini ключ UseIniInProgramDir (еще одна беда, свалившаяся на нашу голову вместе с версией 6.5). Если есть - то ищем INI файлы в соответствии со значением этого ключа (подробности - в HELP).
3.Если там - пусто, то смотрим в [HKEY_CURRENT_USER\Software\Ghisler\Total Commander].
4.Если и там - пусто, то INI лежат в %WINDIR% и названия их - wincmd.ini и wcx_ftp.ini.

Важные замечания

1.Ключи командной строки /I и /F могут быть в любом регистре, причем второй по очереди ключ может быть и без слеша.
2.Пути в ключах командной строки и реестра могут задаваться как полным путем, так и относительным. В путях можно использовать любые переменные окружения, включая %COMMANDER_PATH%. Пути могут быть заданы и как LongNames и в формате 8.3
3.Если пути к файлам заданы явно (в ключах командной строки или реестре), то файлы инициализации могут иметь ЛЮБОЕ имя.

Ну а теперь - поподробнее про анализ командной строки

Для плагина TC все решается сравнительно просто. А все потому, что он выполняется внутри процесса TC, и поэтому получить командную строку можно просто вызвав API-шную функцию GetCommandLine. Кто понимает, о чем я говорю, тому не составит труда извлечь из нее нужные параметры.
Для внешней утилиты все значительно сложнее. Решается эта проблема с использованием ловушек (hooks), труб (pipes) и прочих мудреных вещей. Пройти все круги ада и построить рабочую программу смог только Alexander Asyabrik aka Shura (я о ReloadTC
). Других, увы, не знаю.

Так вот обломали нас в самом начале пути.
Однако, есть возможность получить вожделенные пути и несколько иным способом, если мы вспомним о том, что сам ТС прекрасно осведомлен о местоположении своих INI файлов - достаточно взглянуть на окошко "About".
Итак, вкратце: Находим окно активного экземпляра ТС, шлем ему через SendMessage
команду cm_About, считываем через GetWindowText драгоценную инфу, закрываем окошко About. Если на время выполнения этой процедуры запретить обновление окна, то получится почти незаметно.
Намеренно не говорю о подводных камнях (а то обсуждать будет нечего), а вот положительные стороны данного подхода - налицо. Одним махом находим местоположения обоих INI файлов совершенно независимо от того, как и где задал их пользователь.

P.S. Всего этого разговора могло бы и не быть, если бы глубокоуважаемый Christian Ghisler ввел в обиход пару псевдопеременных $MAIN_INI
и $FTP_INI (подобно имеющимся уже $MYPICTURES, $LOCAL_APPDATA, $COMMON_APPDATA, и т.п.). Ему-то это сделать - плевое дело!
Представьте, как было бы здорово!
Как вам, к примеру, была бы такая команда в меню "Запуск":

Команда: disk:/path/MySuperEditor.exe
Параметры: $MAIN_INI $FTP_INI

Кому так же больно как мне - отпишите Орлу нашему...

Примечание
: начиная с версии 6.55, а точнее - с одной из её бета-версий, в TC появилась поддержка псевдопеременной %commander_ini%. Ура, товарищи! :)
TC 7.0 и старше поддерживают также другие псевдопеременные, список их можно найти здесь.

SAM
Оригинал статьи и её обсуждение