Tkabber Wiki

Config dir
Login

Материал из Tkabber Wiki

Внимание! реализация механизмов, обсуждаемых здесь, интегрирована в транк Ткаббера начиная с ревизии 859 (05 янв 2007). Реализованный механизм изложен ниже.

Также был обновлён раздел #4 "Configuration" документации Ткаббера — читайте tkabber.html на своей системе.

Содержание

Введение

Обсуждение новой схемы поддержки каталога конфигурации Ткаббера.

Идея: отказаться от схемы ~/.tkabber в Windows по причине того, что при существующей схеме каталог конфигурации на любой Windows-системе оказывается не там, где предполагается хранить конфигурацию на данной системе.

Конкретно нас интересует т.н. каталог "application data" ("appdata"). Предполагается хранить настройки Ткаббера в подкаталоге "Tkabber" этого каталога.

Получить путь каталога "appdata" можно тремя способами:

Инфа по системам

(TODO): 95? ME?

Проблемы

Наиболее разумным представляется вызов SHGetSpecialFolderPath, однако это не самый простой путь:

Путь с реестром и окружением не имеет такой "идеологической чистоты", как вызов SHGetSpecialFolderPath.

Рабочий вариант

При старте:

Вопросы:

Juriks, посовещавшись с Kostix, предлагает: Запускать несколько Ткабберов с разными настройками с помощью таких вот скриптов:

@echo off
set TKABBER_HOME=c:\home\vasya_pupkin
start tkabber.exe

То есть искать папку с конфигами в таком порядке:

  1. переменная окружения TKABBER_HOME
  2. реестр
  3. прочие переменные оружения

Kostix комментирует: реализованный в альфе Ткаббера вариант сначала ищет переменную окружения APPDATA, и только в случае неудачи смотрит реестр. Причины простые:

Добавка про SHGetSpecialFolderPath

SHGetSpecialFolderPath «замещена» процедурой SHGetFolderPath начиная с w2k, хотя и доступна на всех системах. Для нас это ничего не значит, так как нам для совместимости со старыми OS необходимо использовать старую версию.

На современных системах SHGetSpecialFolderPath реализована в shell32.dll. Также эта функция содержится в redistributable library SHFolder.dll, которая может включаться в поставку продукта и худо-бедно работать на любой OS. Starpack это, пожалуй, не спасёт, а вот Pack и выше может спокойно её использовать.

Тестовая реализация SHGetSpecialFolderPath через Ffidl

Скрипт

Скрипт, печатающий путевое имя каталога "application data" в Windows.

Создаваемая команда Tcl "SHGetSpecialFolderPath" способна возвращать имя любого стандартного каталога Windows (заданного соотв. ключом "CSIDL_...").

В случае неуспеха команда возвращает пустую строку.

#! /usr/bin/tclsh

package require Ffidl

ffidl::callout dll_SHGetSpecialFolderPath \
    {int pointer-utf16 int int} int \
    [ffidl::symbol shell32.dll SHGetSpecialFolderPathW]

proc SHGetSpecialFolderPath {what create} {
    array set CSIDL {
        CSIDL_DESKTOP   0
        CSIDL_INTERNET  1
        CSIDL_PROGRAMS  2
        CSIDL_CONTROLS  3
        CSIDL_PRINTERS  4
        CSIDL_PERSONAL  5
        CSIDL_FAVORITES 6
        CSIDL_STARTUP   7
        CSIDL_RECENT    8
        CSIDL_SENDTO    9
        CSIDL_BITBUCKET 10
        CSIDL_STARTMENU 11
        CSIDL_DESKTOPDIRECTORY  16
        CSIDL_DRIVES    17
        CSIDL_NETWORK   18
        CSIDL_NETHOOD   19
        CSIDL_FONTS     20
        CSIDL_TEMPLATES 21
        CSIDL_COMMON_STARTMENU  22
        CSIDL_COMMON_PROGRAMS   23
        CSIDL_COMMON_STARTUP    24
        CSIDL_COMMON_DESKTOPDIRECTORY   25
        CSIDL_APPDATA   26
        CSIDL_PRINTHOOD 27
        CSIDL_LOCAL_APPDATA 28
        CSIDL_ALTSTARTUP    29
        CSIDL_COMMON_ALTSTARTUP 30
        CSIDL_COMMON_FAVORITES  31
        CSIDL_INTERNET_CACHE    32
        CSIDL_COOKIES   33
        СSIDL_HISTORY   34
        CSIDL_COMMON_APPDATA    35
        CSIDL_WINDOWS   36
        CSIDL_SYSTEM    37
        CSIDL_PROGRAM_FILES 38
        СSIDL_MYPICTURES    39
        CSIDL_PROFILE       40
        СSIDL_SYSTEMX86     41
        CSIDL_PROGRAM_FILESX86      42
        CSIDL_PROGRAM_FILES_COMMON  43
        СSIDL_PROGRAM_FILES_COMMONX86   44
        CSIDL_COMMON_TEMPLATES      45
        CSIDL_COMMON_DOCUMENTS      46
        CSIDL_COMMON_ADMINTOOLS     47
        CSIDL_ADMINTOOLS    48
        CSIDL_CONNECTIONS   49
        CSIDL_COMMON_MUSIC  53
        CSIDL_COMMON_PICTURES   54
        CSIDL_COMMON_VIDEO  55
        CSIDL_RESOURCES     56
        CSIDL_RESOURCES_LOCALIZED   57
        CSIDL_COMMON_OEM_LINKS      58
        CSIDL_CDBURN_AREA   59
        CSIDL_COMPUTERSNEARME   61
        CSIDL_FLAG_DONT_VERIFY  0x4000
        CSIDL_FLAG_CREATE   0x8000
        CSIDL_FLAG_MASK     0xFF00
    }

    set bCreat [expr {$create ? 1 : 0}]

    set path [string repeat \u0000 300] ;# MAX_PATH is actually 260

    set ok [dll_SHGetSpecialFolderPath 0 $path $CSIDL($what) $bCreat]

    if {$ok} {
        set ix [string first \u0000 $path]
        if {$ix > 0} {
            return [string range $path 0 [expr {$ix - 1}]]
        }
    } else {
        return {}
    }
}

puts "appdata: [SHGetSpecialFolderPath CSIDL_APPDATA false]"

Запускать следует через tclsh, например, так:

C:\> tclsh sh.tcl

wish не имеет открытого канала stdout и puts там ничего интересного не делает.

Можете так же поменять последнюю строку (с puts) на

tk_messageBox -message [SHGetSpecialFolderPath CSIDL_APPDATA false]

и запускать скрипт "просто", например, двойным щелчком мышью на его файле в Explorer.

Замечания

Вписал статью в тиклевое вики.

ANSI (8-bit) vs Unicode (UTF-16)

В любом случае, ANSI версия используется так:

ffidl::callout dll_SHGetSpecialFolderPath \
    {int pointer-utf8 int int} int \
    [ffidl::symbol shell32.dll SHGetSpecialFolderPathA]

Реализация в Ткаббере

Потребует более серьёзного подхода: